gpt4 book ai didi

nhibernate - 流利的 NHibernate 和过滤一对多关系需要多个连接的查询?

转载 作者:行者123 更新时间:2023-12-04 18:22:13 25 4
gpt4 key购买 nike

我最近开始使用 NHibernate,但在实现进一步概述的域模型时遇到了一些麻烦。

我正在寻找的是一种过滤项目与其特定数据存储上的 ItemData 集合之间关系的方法。 DataStores 要么是全局的,在这种情况下它们总是被返回,要么特定于用户身份(基于应用程序实例)。

在 SQL 中,这可以使用一个简单的查询来完成:

SELECT * FROM Items i
INNER JOIN ItemData id ON (i.ItemId=id.ItemId)
LEFT OUTER JOIN Users u ON (id.UserId=u.UserId)
LEFT OUTER JOIN DataStore ds ON (id.DataStoreId=ds.DataStoreId)
WHERE ds.IsGlobal = 1 OR ds.UserId = @userId

数据库结构:
DataStore:
- DataStoreId (PK)
- Name
- Weight
- UserId
- IsGlobal

Item:
- ItemId (PK)
- ... (non-nullable fields)

ItemData:
- ItemDataId (PK)
- ItemId
- DataStoreId
- ... (nullable fields)

领域模型:
public class ItemMap : ClassMap<Item>
{
public ItemMap()
{
Id(x => x.Id, "ItemId");
HasMany(x => x.Data)
.KeyColumn("ItemId")
.ApplyFilter<ItemDataFilter>(..?)
.Cascade.AllDeleteOrphan();
}
}

基本理论是为每个 DataStore 获取一个 ItemData 行,并在相应 DataStore 的权重字段上连接每一列(按权重排序的第一个非空值)。

深入了解是否以及如何在 NHibernate 中实现这一点将不胜感激。

最佳答案

这是我自己发现的,以防其他人正在寻找此信息。

1.创建自定义过滤器:

public class ItemDataFilter : FilterDefinition
{
public ItemDataFilter()
{
WithName("ItemDataFilter").WithCondition("Data.DataStoreId == :DataStoreId").AddParameter("DataStoreId", NHibernate.NHibernateUtil.Int32);
}
}

2.修改你的 Fluent NHibernate 属性映射(使用 .ApplyFilter<>()):
HasMany(x => x.Data)
.KeyColumn("ItemId")
.ApplyFilter<ItemDataFilter>()
.Cascade.AllDeleteOrphan();

3.在您的存储库中启用过滤器并为当前 session 设置它的属性:
public IList<Item> GetItemsByDataStore(int DataStoreId)
{
using (var session = NHibernateHelper.OpenSession())
{
session.EnableFilter("ItemDataFilter").SetParameter("DataStoreId", DataStoreId);
return session.CreateCriteria(typeof(Item)).List<Item>();
}
}

另一种方法是获取每个 Item 的所有 ItemData 并添加另一个执行此过滤的非映射属性。

关于nhibernate - 流利的 NHibernate 和过滤一对多关系需要多个连接的查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5131004/

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