简体   繁体   中英

Entity Framework, Generic loading of related entities with a where condition

I'm trying to create a function that generically loads the related child entities with a filter.

All my entities are derived from my own Base Class "BusinessObject"

public abstract class BusinessObject : BaseObject, IBaseObject, ILocalObject
{
    [Browsable(false)]
    [Key]
    public int ID { get; set; }

    [Browsable(false)]
    public int? HqID { get; set; }

    private bool _deleted;
    [Browsable(false)]
    public bool Deleted
    {
        get { return _deleted; }
        set { CheckPropertyChanged(ref _deleted,  value); }
    }
}

I have created the following function that when supplied an entity will load all the related child objects. When defining my entities, all child collections are flagged by my own attribute "EntityChildCollectionAttribute" so I can easily find the collections I want to load.

    public virtual void OnLoadEntityChildren(object entity)
    {
        var propNames = entity.GetPropertyNames();
        foreach (var propName in propNames.Where(propName => entity.PropertyHasCustomAttribute(propName, typeof(EntityChildCollectionAttribute))))
        {
            MyData.Entry(entity).Collection(propName).Load();                               
        }
    }

This works lovely! My Problem comes when I want to filter the child collection.

In this case I want to only load child entities where Deleted == false.

I cannot work out how to do this!

I have had many attempts and replacing MyData.Entry(entity).Collection(propName).Load(); with

MyData.Entry(entity).Collection(propName).Query().Cast<BusinessObject>().Where(x=>x.Deleted.Equals(false)).Load();

compiles but then I get the error;

"Unable to cast the type 'FmOrderProcessing.Entities.OpDocumentDetail' to type 'FwBaseEntityFramework.BusinessObject'. LINQ to Entities only supports casting EDM primitive or enumeration types."

Any Help/Pointers/Answers will be gratefully received

Thanks in advance

Lance

I was implementing a "Soft Delete" pattern which means the records in the database are flagged as deleted rather than removed (for audit and replication purposes).

All entities are derived from a base definition with a bool Deleted property.

I found the answer here:

https://www.nuget.org/packages/EntityFramework.DynamicFilters

This package allows the definition of global filters in the data context. I fixed my issue with one line of code in the OnModelCreating override.

modelBuilder.Filter("Deleted", (IBaseObject d) =>d.Deleted, false);

The filter function is applied globally to any entity presenting (in my case) the IBaseObject interface.

I hope this helps any body else with a similar issue

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