简体   繁体   中英

Casting my entity variable to a specific (entity) type with EntityFramework

I have some classes like this one below:

public class Driver
{
    public int       Id { get; set; }
    public string    Firstname { get; set; }
    public string    Lastname { get; set; }
    public string    CreatedById { get; set; }
    public DateTime? CreatedTime { get; set; }
    public string    UpdatedById { get; set; }
    public DateTime? UpdatedTime { get; set; }
}

Please note the 4 last fields.

Everytime an entity is created/updated, I call a function to update 4 fields which are present in all my classes (CreatedTime, CreatedById, UpdatedTime, UpdatedById).

The example below is for the Driver class:

    private void UpdateAdditionalData(EntityInfo entityInfo)
    {
        var userId = Current.User.Identity.Name;
        var entity = (Driver)entityInfo.Entity;
        ... 
        if (entityInfo.EntityState == EntityState.Added)
        {
            entity.CreatedTime = DateTime.Now;
            entity.CreatedById = userId;
        }
        if (entityInfo.EntityState == EntityState.Modified)
        {
            entity.UpdatedTime = DateTime.Now;
            entity.UpdatedById = userId;
        }

As you can see, I declare an entity variable which is casted with a prefix (Driver) .

Now I would like to adjust this code to be able to reference any classes and not specifically the Driver class.

I tried something like:

    private void UpdateAdditionalData(EntityInfo entityInfo)
    {
        var userId = Current.User.Identity.Name.ToUpper();   
        var typed = entityInfo.Entity.GetType().Name;
        var entity = (typed)entityInfo.Entity;
        ...

So I declared a typed variable which is the name of the entity for casting my entity.

But it doesn't work, I got an error: the type of namespace 'typed' could not be found.

Any idea how can I accomplish this?

Thanks.

Bottom line of why this doesn't work is normally types are static, compile time data. You're trying to get it at runtime. This means using reflection and invocations which will be complicated.

I think what you want is an interface to work with that's shared across entities.

public interface Auditable
{
    string    CreatedById { get; set; }
    DateTime? CreatedTime { get; set; }
    string    UpdatedById { get; set; }
    DateTime? UpdatedTime { get; set; }
}

Then have your entity implement that interface. Any entity that implements that interface can be used...

var userId = Current.User.Identity.Name.ToUpper();   
var entity = entityInfo.Entity as Auditable;    
if (entity != null) { /* set the audit values */ }

If the entity doesn't implement the interface then you won't actually set the audit values.

Unless I misunderstand you, you need a base type for your entities?

public class Driver : EntityBase
{
    public int       Id { get; set; }
    public string    Firstname { get; set; }
    public string    Lastname { get; set; }
}

Base type...

public class EntityBase
{
    public string    CreatedById { get; set; }
    public DateTime? CreatedTime { get; set; }
    public string    UpdatedById { get; set; }
    public DateTime? UpdatedTime { get; set; }
}

Then you could simply cast to your base type?

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