【问题标题】:Entity Framework, Generic loading of related entities with a where condition实体框架,具有 where 条件的相关实体的通用加载
【发布时间】:2016-05-12 11:26:49
【问题描述】:

我正在尝试创建一个通常使用过滤器加载相关子实体的函数。

我所有的实体都派生自我自己的基类“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); }
    }
}

我创建了以下函数,当提供一个实体时,它将加载所有相关的子对象。 在定义我的实体时,所有子集合都由我自己的属性“EntityChildCollectionAttribute”标记,因此我可以轻松找到我想要加载的集合。

    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();                               
        }
    }

这很好用! 当我想过滤子集合时,我的问题就来了。

在这种情况下,我只想加载 Deleted == false 的子实体。

我不知道该怎么做!

我进行了很多尝试并替换了 MyData.Entry(entity).Collection(propName).Load();与

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

编译但是我得到了错误;

“无法将类型 'FmOrderProcessing.Entities.OpDocumentDetail' 转换为类型 'FwBaseEntityFramework.BusinessObject'。LINQ to Entities 仅支持转换 EDM 基元或枚举类型。”

我们将不胜感激地收到任何帮助/指针/答案

提前致谢

兰斯

【问题讨论】:

  • 有时只写纯sql是最好的答案....如果在EF中变得太复杂,写一个sproc。
  • EF 不知道BusinessObject。它不是映射类型。
  • 对了,我想知道你为什么不用Include。您的代码分别为每个父级加载子集合,也称为 n+1 反模式。
  • @GertArnold - “包含”是否允许您指定通用过滤器?
  • 不,这是一个令人讨厌的限制。有work-araounds

标签: c# entity-framework-6


【解决方案1】:

我正在实施“软删除”模式,这意味着数据库中的记录被标记为已删除而不是已删除(出于审核和复制目的)。

所有实体都派生自具有 bool Deleted 属性的基本定义。

我在这里找到了答案:

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

这个包允许在数据上下文中定义全局过滤器。 我用 OnModelCreating 覆盖中的一行代码解决了我的问题。

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

过滤器函数全局应用于任何呈现(在我的例子中)IBaseObject 接口的实体。

我希望这可以帮助其他有类似问题的人

【讨论】:

    猜你喜欢
    • 2014-10-23
    • 1970-01-01
    • 2021-12-04
    • 2021-05-03
    • 2012-02-07
    • 2011-04-09
    • 1970-01-01
    • 1970-01-01
    • 2013-07-11
    相关资源
    最近更新 更多