gpt4 book ai didi

c# - 在 Entity Framework 6 中为子集合的映射添加条件,类似于 NHibernate 的 "where"

转载 作者:行者123 更新时间:2023-11-30 12:59:04 25 4
gpt4 key购买 nike

在 NHibernate 中,有一个 where 映射允许您在属性映射上指定一个条件,该条件会影响它从数据库中提取的方式。例如,如果我想实现软删除并从集合中排除所有已删除的项目,我可以这样映射它:

FluentNHibernate

// in class ParentMap : ClassMap
HasMany(x => x.Children).Where("IsDeleted = 0");

Hbm.xml

<class name="Parent" table="[Parents]">
<bag cascade="all" lazy="true" name="Children" where="IsDeleted = 0">
<!-- rest of map here -->
</bag>
</class>

Entity Framework 6 中有类似的东西吗?

我找到的最接近的是一个名为 EntityFramework.Filters 的库,它允许您为属性添加全局过滤器,但当该属性是一个集合时它似乎不起作用。


为了更好地说明为什么需要这样的映射,假设我有一个类,其中包含具有递归子实体关系的对象集合(即,相同类型的对象集合)。它们遵循以下基本结构:

public class ReportOutline
{
public long Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public virtual ICollection<OutlineItem> OutlineItems { get; set; }
}

public class OutlineItem
{
public long Id { get; set; }
public string Name { get; set; }

public long ReportOutlineId { get; set; }
public long? ParentOutlineItemId { get; set; }

public virtual ReportOutline ReportOutline { get; set; }
public virtual OutlineItem ParentOutlineItem { get; set; }

public virtual ICollection<OutlineItem> OutlineItems { get; set; }
}

这些是用 EF fluent API 映射的,如下所示:

modelBuilder.Entity<ReportOutline>()
.HasKey(o => o.Id)
.HasMany(o => o.OutlineItems)
.WithRequired(i => i.ReportOutline)
.HasForeignKey(i => i.OutlineId);

modelBuilder.Entity<OutlineItem>()
.HasKey(p => p.Id)
.HasMany(p => p.OutlineItems)
.WithOptional(c => c.ParentOutlineItem)
.HasForeignKey(c => c.ParentOutlineItemId);

这产生了正确的数据库结构,我的记录看起来很好。下面是 OutlineItems 表在 ReportOutline 上有两个项目的示例,如果一个表有两个子项目(总共四个):

Id    Name           ReportOutlineId    ParentOutlineItemId
1 Introduction 1 NULL
2 Pets 1 NULL
3 Cats 1 2
4 Dogs 1 2

ReportOutline 通过 DbContext 加载时,但是,由于 ReportOutlineId 与大纲的 Id 匹配, ReportOutline.OutlineItems 正在填充所有四个项目。这导致子项出现在父项和主大纲本身的下方:

Title:  My Report
Author: valverij

I. Introduction (Id: 1)
II. Pets (Id: 2)
A. Cats (Id: 3)
B. Dogs (Id: 4)
III. Cats (Id: 3) <--- Duplicated
IV. Dogs (Id: 4) <--- Duplicated

现在,如果我将 NHibernate 与 FluentNhibernate 一起使用,我可以在实体映射上指定一个 where 条件,这样 ReportOutline.OutlineItems 只有 拉取父项:

// in ReportOutlineMap
HasMany(x => x.OutlineItems).Where("ParentOutlineItemId IS NULL");

否则,我将不得不记住通过显式处理OutlineItem 集合的预写查询访问ReportOutline 对象.

最佳答案

您可以将“RootOutlineItems”属性添加到为您过滤的 ReportOutline 类,然后在您只需要第一级时调用它:

public class ReportOutline
{
public long Id { get; set; }
public string Title { get; set; }
public string Author { get; set; }
public virtual ICollection<OutlineItem> OutlineItems { get; set; }
public ICollection<OutlineItem> RootOutlineItems {
get {
return OutlineItems.Where(p=> p.ParentOutlineItem == null);
}
}
}

另一种选择是使 OutlineItem 的 ReportOutline 可为空,并且只设置 ReportOutline 或 ParentOutlineItem 属性,但这有点不确定,而且如果您需要导航树永远想要所有的元素。

关于c# - 在 Entity Framework 6 中为子集合的映射添加条件,类似于 NHibernate 的 "where",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27324004/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com