使用实体框架基础模型和父类调用字段

时间:2014-10-20 20:11:04

标签: c# entity-framework-6

我试图在我的实体框架模型中使用基类......

我有以下基类:

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; }
    }

然后我有一个继承自它的类:

public class Family : BaseModel

基本上我希望能够使用以下内容设置这些基本字段:

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;

    }

然后调用如:

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

我得到了这个,但我想我能做到这一点,还是我完全走错了路?

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

3 个答案:

答案 0 :(得分:1)

您可以将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;
    }
}

然后,您可以在继承BaseModel

的所有类上使用它
Models.Family efFamily = _mapper.Map(family);
efFamily.SetBaseData(family.CurrentUserId);

答案 1 :(得分:1)

一种可能性是通过创建基础SaveChanges()类来覆盖DataContext函数。

这样做,您将永远不必在映射后调用任何函数,实体框架将为您执行此操作,并且只会更新updateddt字段(如果表中存在)。

以下是我们的所作所为:

像这样创建一个接口IDataContext:

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

   int SaveChanges();
}

然后为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();
    }
}

我们正在使用Code First,因此我不确定这是否适用于所有情况。

答案 2 :(得分:0)

您可以这样做,但是您需要传入BaseModel,因为参数包含ref修饰符。如果不这样做,编译器必须将变量打包,然后ref会回复给您,并且您将丢失该值。而是这样做:

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