Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Configure Entity Framework to load a predefined object

I have this class

public class Status
{
    private string status;
    public string StatusName
    {
        get
        {
            return status;
        }
    }
    private Status (string _status)
    {
        status = _status;
    }
    public static readonly Status Open = new Status("Open");
    public static readonly Status Closed = new Status("Closed");
}  

Using Code First, can I configure EF to load one of the predefined objects (Open, Closed) instead of trying to create a new one?
Or is there a better way to accomplish a similar behavior?

like image 635
user5252279 Avatar asked Nov 28 '25 02:11

user5252279


1 Answers

Current EF version does not provide any hook to replace object materialization (unless you download source code an try to implement it yourselves). That means EF will always create its own status and to be able to do that it will also need your Status class to match its rules. I don't know why you need this but if you really need always the same object instances for your statuses you can hack it.

First you need to modify your Status class for EF:

public class Status{
    // EF needs access to your property
    public string StatusName { get; private set; }

    // EF needs parameterless constructor because it will create instances
    private Status() {}

    private Status (string status) {
        StatusName = status;
    }

    public static readonly Status Open = new Status("Open");
    public static readonly Status Closed = new Status("Closed");
}  

Now you need to replace the original Status created by EF with your own:

public Context() : base() {
    var objectContext = ((IObjectContextAdapter)this).ObjectContext;
    objectContext.ObjectMaterialized += OnObjectMaterialized;
}

private void OnObjectMaterialized(object sender, ObjectMaterializedEventArgs args) {
    var objectContext = (ObjectContext)sender;
    var entity = args.Entity as Entity;
    if (entity != null) {
        switch (entity.Status.StatusName) {
            case "Open":
                entity.Status = Status.Open;
                break;
            case "Closed":
                entity.Status = Status.Closed;
                break;
        }

        // This is necessary because previous code made your object modified
        objectContext.DetectChanges();
        var entry = objectContext.ObjectStateManager.GetObjectStateEntry(entity);
        entry.AcceptChanges();
    }
}

It is ugly hack but if you really need this you will have to do something similar.

like image 117
Ladislav Mrnka Avatar answered Dec 02 '25 04:12

Ladislav Mrnka



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!