简体   繁体   English

使用实体框架基础模型并在父类上调用字段

[英]using entity framework base model and calling fields on parent class

I'm trying to use a base class with my entity framework models... 我正在尝试在我的实体框架模型中使用基类...

I have the following baseclass: 我有以下基类:

public class BaseModel
    {
        [Key]
        public int Id { get; set; }
        public DateTime CreatedDate { get; set; }
        public DateTime UpdatedDate { get; set; }
        public DateTime? ExpiryDate { get; set; }

        public bool IsActive { get; set; }
        public Guid CreatedBy { get; set; }
        public Guid UpdatedBy { get; set; }
    }

I then have a class that inherits from it: 然后,我有了一个继承自它的类:

public class Family : BaseModel

Basically i then want to be able to set these base fields using something like: 然后,基本上我希望能够使用类似以下内容来设置这些基本字段:

private void SetBaseData(ref BaseModel baseModel, Guid currentUserId)
    {
        if (baseModel.Id < 1)
        {
            baseModel.CreatedDate = _datetime.Now();
            baseModel.CreatedBy = currentUserId;
            baseModel.IsActive = true;
        }

        baseModel.UpdatedDate = _datetime.Now();
        baseModel.UpdatedBy = currentUserId;

    }

And then called like: 然后像这样调用:

Models.Family efFamily = _mapper.Map(family);
SetBaseData(ref efFamily, family.CurrentUserId);

I'm getting this but I thought I;d be able to do this or am I completely going down the wrong route? 我知道了,但是我认为我能够做到这一点,还是我完全走错了路线?

Error   27  Argument 1: cannot convert from 'ref FamilyOrganiser.Repository.EntityFramework.Models.Family' to 'ref FamilyOrganiser.Repository.EntityFramework.Models.BaseModel'

You could add SetBaseData method to your BaseModel class, then it would look like this: 您可以将SetBaseData方法添加到BaseModel类,然后将如下所示:

public class BaseModel
{
     // your code, properties, etc.
     ...

    public void SetBaseData(Guid currentUserId)
    {
        if (this.Id < 1)
        {
            this.CreatedDate = _datetime.Now();
            this.CreatedBy = currentUserId;
            this.IsActive = true;
        }

        this.UpdatedDate = _datetime.Now();
        this.UpdatedBy = currentUserId;
    }
}

Then you can use it like this on all classes that inherit your BaseModel : 然后,您可以像这样在继承BaseModel所有类上使用它:

Models.Family efFamily = _mapper.Map(family);
efFamily.SetBaseData(family.CurrentUserId);

One possibility is to over ride the SaveChanges() function by creating a base DataContext class. 一种可能是通过创建基本DataContext类来超越SaveChanges()函数。

Doing it this way, you will never have to call any function after mapping, entity framework will do it for you and will only update the updateddt field if it exists in the table. 这样,映射后就无需调用任何函数,实体框架将为您完成此操作,并且仅当表中存在updatedt字段时才更新该字段。

Here is what we did: 这是我们所做的:

Create an interface IDataContext like this: 创建一个接口IDataContext,如下所示:

public interface IMyDataContext
{
   DbConnection Connection { get; }
   IDbSet<MyClass> MyClasses{ get; }

   int SaveChanges();
}

and then create a partial class for the DataContext 然后为DataContext创建一个局部类

public partial class MyDataContext : DbContext, IMyDataContext
{
    static HealthDataContext()
    {
      Database.SetInitializer<HealthDataContext>(null);
    }

    public IDbSet<MyClass> MyClasses { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
      modelBuilder.Configurations.Add(new MyClassMap());

    }

    public override int SaveChanges()
    {
      var changeSet = ChangeTracker.Entries();

      if (changeSet != null)
      {
        foreach (var entry in changeSet.Where(c => c.State == EntityState.Deleted || c.State == EntityState.Added || c.State == EntityState.Modified))
        {

          switch (entry.State)
          {
            case EntityState.Added:
              if (entry.Entity.GetType().GetProperty("createddt") != null)
              {
                entry.Entity.GetType().GetProperty("createddt").SetValue(entry.Entity, new Health.Core.Helpers.RealClock().UtcNow);
              }

              break;
            case EntityState.Deleted:
              break;
            case EntityState.Detached:
              break;
            case EntityState.Modified:
              if (entry.Entity.GetType().GetProperty("updateddt") != null)
              {
                entry.Entity.GetType().GetProperty("updateddt").SetValue(entry.Entity, new Health.Core.Helpers.RealClock().UtcNow);
              }

              break;
            case EntityState.Unchanged:
              break;
            default:
              break;
          }

        }
      }
      return base.SaveChanges();
    }
}

We are using Code First so I'm not sure if this will work in all scenarios. 我们正在使用Code First,所以我不确定这是否在所有情况下都适用。

You can do it but you need to pass in a BaseModel as the parameter has the ref modifier. 您可以执行此操作,但是由于参数具有ref修饰符,因此需要传入BaseModel If you don't, the compiler would have to box your variable, then ref is back to you, and you'd lose the value. 如果您不这样做,则编译器将必须对变量进行装箱,然后ref会返回给您,您将失去该值。 Instead do this: 而是这样做:

Family efFamily = new Family();
BaseModel m = (BaseModel)efFamily;
SetBaseData(ref m, new Guid());

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM