流利的NHibernate和过滤一对多关系查询需要多个连接? [英] Fluent NHibernate and filtering one-to-many relationship on query requiring multiple joins?

查看:165
本文介绍了流利的NHibernate和过滤一对多关系查询需要多个连接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



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

在SQL中,可以使用简单查询:

pre code $ SELECT $ FROM $ item $ INNER JOIN ItemData id ON(i.ItemId = id.ItemId)
LEFT OUTER JOIN用户u ON(id.UserId = u.UserId)
LEFT OUTER JOIN DataStore ds ON(id.DataStoreId = ds.DataStoreId)
WHERE ds.IsGlobal = 1 OR ds。 UserId = @userId

数据库结构:

<$数据存储:
- DataStoreId(PK)
- 名称
- 重量
- 用户ID
- IsGlobal

项目:
- ItemId(PK)
- ...(不可为空的字段)

ItemData:
- ItemDataId(PK)
- ItemId
- DataStoreId
- ...(可空字段)

域模型:

  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中是否以及如何实现这一点将不胜感激。

解决方案

这里有些资料是我自己发现的。
创建自定义过滤器:

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




$ b修改你的Fluent NHibernate属性映射(使用。 ApplyFilter<>()):

  HasMany(x => x.Data)
.KeyColumn(ItemId )
.ApplyFilter< ItemDataFilter>()
.Cascade.AllDeleteOrphan();

3.在您的存储库中启用筛选器并为其设置属性:

  public IList< Item> GetItemsByDataStore(int DataStoreId)
使用(var session = NHibernateHelper.OpenSession())
{
session.EnableFilter(ItemDataFilter)。SetParameter(DataStoreId,DataStoreId );
return session.CreateCriteria(typeof(Item))。List< Item>();




$ b $ p
$ b另一种方法是获取所有ItemData为每个项目添加另一个非映射的属性,做这个过滤。

I recently got started with NHibernate and am having some trouble implementing the domain model outlined further down.

What I'm looking for is a way to filter the relationship between an Item and it's ItemData collection on specific DataStores. DataStores are either global, in which case they are always returned, or specific to a user identity (based on application instance).

In SQL this can be accomplished using a simple query:

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

Database structure:

DataStore:
- DataStoreId (PK)
- Name
- Weight
- UserId
- IsGlobal

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

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

Domain model:

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

The basic theory is to fetch one ItemData row per DataStore and join each column on the weight field of the respective DataStore (first non-null value ordered by weight).

Insight as to if and how this could be accomplished in NHibernate would be much appreciated.

解决方案

Heres what I've found myself in case anyone else is looking for this information.

1.Create a custom filter:

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

2.Modify your Fluent NHibernate property mapping (with .ApplyFilter<>()):

HasMany(x => x.Data)
    .KeyColumn("ItemId")
    .ApplyFilter<ItemDataFilter>()
    .Cascade.AllDeleteOrphan();

3.In your repository enable the filter and set it's property for the current 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>();
    }
}

Another way to do this would be to fetch all ItemData for each Item and add another non-mapped property that does this filtering.

这篇关于流利的NHibernate和过滤一对多关系查询需要多个连接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆