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.