简体   繁体   中英

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:

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 :

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.

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.

Here is what we did:

Create an interface IDataContext like this:

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

   int SaveChanges();
}

and then create a partial class for the 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.

You can do it but you need to pass in a BaseModel as the parameter has the ref modifier. If you don't, the compiler would have to box your variable, then ref is back to you, and you'd lose the value. Instead do this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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