C# 具有不同根实体类型的QueryOver ProjectionList
我在试图重用NHibernate QueryOvers中的投影列表时遇到了问题。我不知道如何为不同的根实体重用东西 对象模型大致表示为: 早餐一对多糕点多对零或一咖啡 这两个独立的查询大致如下:C# 具有不同根实体类型的QueryOver ProjectionList,c#,nhibernate,fluent-nhibernate,queryover,C#,Nhibernate,Fluent Nhibernate,Queryover,我在试图重用NHibernate QueryOvers中的投影列表时遇到了问题。我不知道如何为不同的根实体重用东西 对象模型大致表示为: 早餐一对多糕点多对零或一咖啡 这两个独立的查询大致如下: session.QueryOver() .Where(b=>b.Id==searchId) .Inner.JoinQueryOver(b=>b.糕点,()=>糕点) .Left.JoinAlias(p=>p.Coffee,()=>Coffee) .选择(投影) .TransformUsing(Trans
session.QueryOver()
.Where(b=>b.Id==searchId)
.Inner.JoinQueryOver(b=>b.糕点,()=>糕点)
.Left.JoinAlias(p=>p.Coffee,()=>Coffee)
.选择(投影)
.TransformUsing(Transformers.AliasToBean())
.List();
session.QueryOver()
.Where(c=>c.Id==searchId)
.Inner.JoinQueryOver(c=>c.糕点,()=>pastry)
.选择(投影)
.TransformUsing(Transformers.AliasToBean())
.List();
我尝试重用的常见投影如下所示:
public ProjectionList GetSharedProjections(Coffee coffeeAlias)
{
/* Same as above except with "coffeeAlias"
}
session.QueryOver<Coffee>(() => coffee)
.Select(GetSharedProjections(() => coffee));
var projections=projections.ProjectionList()
.Add(projects.Property(()=>pastry.Name,()=>target.PastryName))
.Add(projects.Property(()=>coffee.Name,()=>target.CoffeeName));
这些使用别名的投影在第一个查询(root:breaken)中工作得很好,因为它们不试图提取根实体上的属性。在第二个查询(root:Coffee)中,它爆炸性地说它在Coffee上找不到'Coffee.Name',因为它不喜欢别名。QueryOver(()=>coffee)语法没有帮助,因为它实际上没有将“coffee”注册为别名,它只是将其用于类型推断。哦,该死的,这就是问题所在。有一个愚蠢的应用程序基础架构正在破坏别名语法,而不是实际使用下面的别名版本
第二个查询希望投影看起来像:
var projections=projections.ProjectionList()
.Add(projects.Property(()=>pastry.Name,()=>target.PastryName))
.Add(projects.Property(c=>c.Name,()=>target.CoffeeName));
但是,这现在与第一个查询不兼容
是否有任何方法可以实现这一点,这样我就可以在不知道根实体类型的情况下投影属性?我认为您需要做的就是在
会话中分配coffee
别名。QueryOver
调用:
Coffee coffee = null;
session.QueryOver<Coffee>(() => coffee)
/* etc */
然后有一些代码调用了助手方法:
session.QueryOver<Coffee>(() => coffee)
.Select(GetSharedProjections());
然后传入您的别名:
session.QueryOver<Coffee>(() => coffee)
.Select(GetSharedProjections(coffee));
然后,您可以将getSharedProject
方法更改为采用表达式形式的别名:
public ProjectionList GetSharedProjection(Expression<Func<Coffee>> coffeeAlias)
{
TargetDTO target = null;
var projections = Projections.ProjectionList()
.Add(BuildProjection<Coffee>(coffeeAlias, c => c.CoffeeName))
.WithAlias(() => target.CoffeeName);
}
public ProjectionList GetSharedProjection(表达式coffeeAlias)
{
TargetDTO target=null;
var projections=projections.ProjectionList()
.Add(BuildProjection(coffeeAlias,c=>c.CoffeeName))
.WithAlias(()=>target.CoffeeName);
}
现在,调用您的方法如下所示:
public ProjectionList GetSharedProjections(Coffee coffeeAlias)
{
/* Same as above except with "coffeeAlias"
}
session.QueryOver<Coffee>(() => coffee)
.Select(GetSharedProjections(() => coffee));
session.QueryOver(()=>coffee)
.选择(GetSharedProject(()=>coffee));
当有人更改你的别名时,你就被覆盖了。您还可以在许多查询中安全地使用此方法,而不必担心别名变量的实际名称
免责声明:以下是我个人博客的链接
您可以通过这种方式找到有关构建查询的更多信息。这正是解决方案!我以前试过这个,但我发现我的应用程序有愚蠢的自定义基础设施包装NHibernate调用,这打破了QueryOver(()=>废话)的别名版本。我知道别名的问题,深入研究NHibernate实现很有趣。我已经在使用表达式作为解决方法。其他新闻:哇。你的博客是我成功地与QueryOver合作的唯一原因,现在你在这里回答我的问题。谢谢!:-)