Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/88.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NHibernate给Linq找没有写过书的作者_C#_Sql_Linq_Nhibernate - Fatal编程技术网

C# NHibernate给Linq找没有写过书的作者

C# NHibernate给Linq找没有写过书的作者,c#,sql,linq,nhibernate,C#,Sql,Linq,Nhibernate,我以作者和书籍为例,使解释变得简单。作者-书有一对多的关系,即一个作者可以写许多书。映射是使用FluentHibernate完成的,它们没有任何特殊之处 我试图询问那些还没有写过书的作者。但是当查看在NHibernate Profiler中生成的查询时,它并不是我所期望的。你们能把这个错误处理掉吗 我期望的结果来自下面的查询 select a.AuthorName ,a.AuthorId from Authors a left outer join Books b on a.Aut

我以作者和书籍为例,使解释变得简单。作者-书有一对多的关系,即一个作者可以写许多书。映射是使用FluentHibernate完成的,它们没有任何特殊之处

我试图询问那些还没有写过书的作者。但是当查看在NHibernate Profiler中生成的查询时,它并不是我所期望的。你们能把这个错误处理掉吗

我期望的结果来自下面的查询

select a.AuthorName
       ,a.AuthorId from Authors a left outer join Books b on a.AuthorId = b.AuthorId
where b.AuthorId is null
实际生成的查询如下所示

SELECT AuthorId,
       AuthorName,
       CreatedAt
FROM   Authors
WHERE  AuthorId is null
为上述提供的映射

public class AuthorsMap : ClassMap<Author>
{

    public AuthorsMap()
    {
        Table("Authors");
        LazyLoad();
        Id(x => x.AuthorId).GeneratedBy.Identity().Column("AuthorId");
        Map(x => x.AuthorName).Column("AuthorName").Not.Nullable();
        Map(x => x.CreatedAt).Column("CreateDatetime").Not.Nullable();
        HasMany(x => x.Books).KeyColumn("AuthorId");
    }
}
公共类作者映射:类映射
{
公共作者地图()
{
表(“作者”);
懒散的负荷();
Id(x=>x.AuthorId).GeneratedBy.Identity()列(“AuthorId”);
Map(x=>x.AuthorName).Column(“AuthorName”).Not.Nullable();
Map(x=>x.CreatedAt).Column(“CreateDatetime”).Not.Nullable();
有很多(x=>x.Books);
}
}
上面是为作者提供的映射,下面是为书籍提供的映射

public class BooksMap : ClassMap<Books>
{
    public BooksMap()
    {
        Table("Books");
        LazyLoad();
        Id(x => x.BookId).GeneratedBy.Identity().Column("BookId");
        References(x => x.Author).Column("AuthorId");
        Map(x => x.BookName).Column("BookName").Not.Nullable();
    }
}
公共类BooksMap:ClassMap
{
公共图书地图()
{
表(“书籍”);
懒散的负荷();
Id(x=>x.BookId).GeneratedBy.Identity()列(“BookId”);
引用(x=>x.Author).列(“authord”);
Map(x=>x.BookName).Column(“BookName”).Not.Nullable();
}
}
查询按如下方式调用

Session.Linq<Author>().Where(author => author.Books == null).ToList();
Session.Linq().Where(author=>author.Books==null.ToList();
上面的另一种风格导致了对象引用错误

Session.Linq<Author>().Where(author => author.Books.Count == 0).ToList();
Session.Linq().Where(author=>author.Books.Count==0.ToList();
性能问题:

@Ocelot20的答案有效,但正在生成N+1查询以查找记录

Session.Linq().Where(author=>!author.Books.Any()0.ToList()

榜样

作者1、2、3没有书籍,则在执行任何()时运行以下查询

从AuthorId=1的书籍中选择AuthorId、BookId、BookName

从AuthorId=2的书籍中选择AuthorId、BookId、BookName

从AuthorId=3的书籍中选择AuthorId、BookId、BookName

这是怎么发生的

这有用吗

Session.Linq<Author>().Where(author => !author.Books.Any()).ToList()
Session.Linq().Where(author=>!author.Books.Any()).ToList()

我明白了为什么
author.Books==null
不起作用,因为它应该是一个空集合,而不仅仅是完全为null。不过我对nhibernate不是很熟悉,所以我不能对配置发表评论。这就是我使用Linq编写查询的方法。

在这种情况下,我建议使用子查询而不是JOIN。原因是,一旦我们需要切换查询以找出拥有一些书籍的作者,联接将乘以结果集(拥有两本书籍的作者将被列出两次等)

另外,让我们将NHibernate本机Linq提供程序语法与
Query
扩展一起使用(返回required
IQueryable
) 实现这一点的语法是:

次选择:

var subquery = session.Query<Book>()
    .Select(b => b.Author.AuthorId)
    ;
var subquery=session.Query()
.Select(b=>b.Author.authord)
;
没有任何书籍的一组作者

var list = session.Query<Author>()
    .Where(a => !subquery.Contains(a.AuthorId))
    ;
var list=session.Query()
.Where(a=>!subquery.Contains(a.AuthorId))
;

如果我们想要获得拥有一些书籍的作者列表,我们可以删除NOT操作符(!)并应用分页(
Take()
Skip()
),这将返回正确的结果,而不是成倍的结果。

这很有效,但是。它的性能最低。我正在编辑我的问题,以包括如果我实现
Any()
@Deeptechtons会发生什么:一些快速的谷歌搜索似乎表明,在nhibernate中,您需要在映射中使用某种
fetch
设置,以指示在这种情况下它应该使用联接。