编辑我为这一个问题重新制作了整个项目.因此,我重新提出了这个问题.
我希望能够有效地避免N + 1和笛卡尔联接将第4级深层实体与第三级复合键连接在一起.
我正在寻找这个只在几个查询中完成,而不是延迟加载,而不是只是将所有表连接在一起.
A - (很多) - > B - (很多) - > C - (复合,单) - > D.
就像是:
Select * From A Left Join B On A.Id = B.AId
Select * From B Left Join C On B.Id = C.BId Inner Join D On C.DId = D.Id
Run Code Online (Sandbox Code Playgroud)
这是使用的代码这是一个功能齐全的应用程序.我使用NuGet安装Sqlite x86,StructureMap,NHProf,Fluent NH.
StructureMapServiceLocator:
namespace MyTest.NHibernateTest
{
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.ServiceLocation;
using StructureMap;
public class StructureMapServiceLocator : ServiceLocatorImplBase
{
private readonly IContainer _container;
public …Run Code Online (Sandbox Code Playgroud) 我正在尝试这样做:
var list = Session.QueryOver<Person>()
.Where(x => x.LastName.Contains(searchText))
.List<Person>();
Run Code Online (Sandbox Code Playgroud)
但我收到此错误:无法识别的方法调用:System.String:Boolean包含(System.String)
你有好主意吗 ?
更新:
public class Person
{
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试将SQL查询转换为NHibernate QueryOver语法,但我不明白如何按计数投影进行排序.
这就是SQL Query的样子:
select top 10 v.intVoteUserID, COUNT(v.intVoteUserID)
from Group_MessageVotes v
where v.dtmVote > :date
group by v.intVoteUserID
order by COUNT(v.intVoteUserID) desc
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
我想模拟这个查询:
SELECT * FROM FOO WHERE ID IN (1,2,3)
Run Code Online (Sandbox Code Playgroud)
我怎么能在FNH这样做?
var ids = new List<int>{1,2,3};
var results = session.QueryOver<Foo>().Where( x=> ids.Contains(x.id) );
Run Code Online (Sandbox Code Playgroud)
但这不起作用,只是给了我一个"无法识别的方法调用"异常.
有任何想法吗?这必须是一个共同的要求.
我已经阅读了很多关于同样错误的问题,但没有找到与我的确切问题相符的问题.我正在尝试使用Fluent NHibernate访问对象的属性,它本身是根对象的一部分.一些答案说我需要使用投影,其他我需要使用连接,我认为它应该通过延迟加载.
这是我的两个类以及Fluent映射:
艺术家班
public class Artist
{
public virtual int Id { get; set; }
public virtual string Name { get; set; }
public virtual IList<Album> Albums { get; set; }
public virtual string MusicBrainzId { get; set; }
public virtual string TheAudioDbId { get; set; }
public Artist() { }
}
public class ArtistMap : ClassMap<Artist>
{
public ArtistMap()
{
LazyLoad();
Id(a => a.Id);
Map(a => a.Name).Index("Name");
HasMany(a => a.Albums)
.Cascade.All();
Map(a => a.MusicBrainzId);
Map(a => a.TheAudioDbId);
} …Run Code Online (Sandbox Code Playgroud) 我有一个看起来像这样的对象模型(伪代码):
class Product {
public ISet<Product> Recommendations {get; set;}
public ISet<Product> Recommenders {get; set;}
public ISet<Image> Images {get; set; }
}
Run Code Online (Sandbox Code Playgroud)
当我加载给定的产品并想要显示其推荐的图像时,我遇到了N + 1问题.(建议是延迟加载的,然后循环调用每个的.Images属性.)
Product -> Recommendations -> Images
Run Code Online (Sandbox Code Playgroud)
我想要做的是急切地加载图表的这个特定部分,但我无法弄清楚如何做到这一点.我可以热切地加载建议,但不能加载他们的图像.这是我一直在尝试的,但它似乎不起作用:
//get the IDs of the products that will be in the recommendations collection
var recommendedIDs = QueryOver.Of<Product>()
.Inner.JoinQueryOver<Product>(p => p.Recommenders)
.Where(r => r.Id == ID /*product we are currently loading*/)
.Select(p => p.Id);
//products that are in the recommendations collection should load their
//images eagerly
CurrentSession.QueryOver<Product>()
.Fetch(p => p.Images).Eager
.Where(Subqueries.WhereProperty<Product>(p …Run Code Online (Sandbox Code Playgroud) 我需要在子集合上做一个子查询,但我无法让它工作.
我试过这个
Task tAlias = null;
List<Task> result = session.QueryOver<Task>(() => tAlias)
.Where(Restrictions.In(Projections.Property(() => tAlias.Course.Id), courseIds))
.WithSubquery.WhereExists(QueryOver.Of<CompletedTask>().Where(x => x.Student.StudentId == settings.StudentId))
().ToList();
Run Code Online (Sandbox Code Playgroud)
但我得到了
如果没有投影,则无法在标准上使用子查询.
我正在将NHibernate 3.0与LINQ提供程序和QueryOver一起使用.有时我想急切加载相关数据,并且在LINQ和QueryOver中都有"获取"方法.现在我有一个特殊的场景,我想在第二层上不直接加载属性,例如:
Foo f = ...;
f.A.B.C
Run Code Online (Sandbox Code Playgroud)
使用LINQ没有问题,因为您可以使用"ThenFetch"方法"链接"提取,如:
var result = Session.Query<Foo>().Fetch(a => a.A).ThenFetch(b => b.B).ThenFetch(c => c.C).ToList();
Run Code Online (Sandbox Code Playgroud)
在QueryOver中没有这样的方法,那么如何才能获得相同的结果呢?
提前致谢.
我有个问题.我有人和猫.每个Person都有一些Cats(Cats中有一个外键指向Persons中的主键).每只猫都有一个年龄.我想选择有"老"猫的人.我想要这些人的所有猫,而不仅仅是"老"猫.我需要使用QueryOver语法来完成它.
在T-SQL中它将是这样的:
SELECT P.*, C.*
FROM Persons P
LEFT JOIN Cats C
ON P.Id = C.OwnerId
WHERE EXISTS (
SELECT 1
FROM Cats C2
WHERE P.Id = C2.OwnerId AND C2.Age > 5)
Run Code Online (Sandbox Code Playgroud)
我知道我必须使用子查询,并且我可以轻松地使用"旧的"nhibernate语法(Criteria/DetachedCriteria),但我无法在QueryOver语法中执行此操作.
我不想要"IN"状态.我的主键是一个复杂的键,所以我无法使用IN.
var persons = session.QueryOver<Person>.WithSubquery.WhereExists( ??? );
Run Code Online (Sandbox Code Playgroud) 我想使用查询来给我一个对象
public class TaskMap : ClassMap<Task>
{
public TaskMap()
{
Table("Tasks");
Id(x => x.TaskId);
Map(x => x.TaskName).NvarcharWithMaxSize().Not.Nullable();
Map(x => x.Description).NvarcharWithMaxSize();
Map(x => x.DueDate).Not.Nullable();
HasMany(x => x.PersonalTaskReminders).Inverse();
HasMany(x => x.TaskReminders).Inverse();
References(x => x.Course).Not.Nullable();
HasMany(x => x.CompletedTasks);
}
}
[Serializable()]
public class Task
{
public virtual int TaskId { get; private set; }
public virtual string TaskName { get; set; }
public virtual string Description { get; set; }
public virtual DateTime DueDate { get; set; }
public virtual IList<PersonalTaskReminder> PersonalTaskReminders { …Run Code Online (Sandbox Code Playgroud)