Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.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阅读儿童收藏?_C#_Nhibernate - Fatal编程技术网

C# 如何阻止NHibernate阅读儿童收藏?

C# 如何阻止NHibernate阅读儿童收藏?,c#,nhibernate,C#,Nhibernate,我的数据库中有文档列表。每个文档都有子元素的集合。现在,我的设想是: -读取文档(仅从文档表) -关闭会话,让用户做一些工作 但当我这样做时,文档会尝试在某些地方加载子元素。我不想要它。我只想明确地阅读子元素。对于第一部分,我只需要阅读简单的文档值 那么有没有办法对nHibernate说:“嘿,千万别读这个收藏!”将你的收藏的延迟加载设置为Lazy或Extra,也许你的设置为NoLazy(又称为渴望加载) 最好将其设置为Extra,而不是仅设置为Lazy。因为当您只想获取子集合的.Count()

我的数据库中有文档列表。每个文档都有子元素的集合。现在,我的设想是: -读取文档(仅从文档表) -关闭会话,让用户做一些工作

但当我这样做时,文档会尝试在某些地方加载子元素。我不想要它。我只想明确地阅读子元素。对于第一部分,我只需要阅读简单的文档值


那么有没有办法对nHibernate说:“嘿,千万别读这个收藏!”

将你的收藏的延迟加载设置为
Lazy
Extra
,也许你的设置为
NoLazy
(又称为渴望加载)

最好将其设置为
Extra
,而不是仅设置为
Lazy
。因为当您只想获取子集合的
.Count()
.Any()
时,它将阻止NHibernate获取子集合的行
Extra
就像是lazy的一个更懒惰的版本:)

NoLazy/快速加载

var post = session.Get<Post>(1);
var commentsCount = post.Comments.Count()
将从数据库中加载帖子的评论:

select * from comments where post_id = 1;
.Count()
,只发生在应用程序端

使用
var commentscont=post.Comments.Count()
,NHibernate将只发出Count查询,而不是读取所有行

select count(*) from comments where post_id = 1
下面是一个示例配置,用于设置子集合的加载机制。如果使用NHibernate的自动映射,请在事件上设置该设置:


当您需要急切地加载配置为
惰性
额外
的子集合时,使用

作为临时解决方案我创建了一个简单的hack:

public class Document
{
    IList<Periods> periods;
    public virtual IList<Period> Periods
    {
        get { return periods; }
        set { periods = value; }
    }

    public virtual void ResetPeriods()
    {
        periods = new List<Period>();
    }
}
公共类文档
{
IList期;
公共虚拟IList周期
{
获取{返回周期;}
设置{periods=value;}
}
公共虚拟空重置周期()
{
句点=新列表();
}
}
这就是我获取文件的方式:

db.BeginTransaction();
IList<Document> list = db.Get<Document>();
db.CommitTransaction();

List<Document> result = new List<Document>();
foreach (var item in list)
{
    item.ResetPeriods(); //todo: HACK! Preventing from lazy load of periods
    result.Add(item);
}


return result;
db.BeginTransaction();
IList list=db.Get();
db.CommitTransaction();
列表结果=新列表();
foreach(列表中的变量项)
{
item.ResetPeriods();//todo:HACK!防止周期的延迟加载
结果.添加(项目);
}
返回结果;
当然,此集合被映射为惰性。
必须将子集合(句点)定义为back变量,因为它阻止NHibernate代理使用属性getter。

我找到了导致文档句点从数据库加载的原因,即使您不访问文档的句点属性

名称空间NHibernateFetchJoinTest2
{
使用制度;
使用NHibernateFetchJoinTest2.DomainMapping;
使用NHibernateFetchJoinTest2.Domains;
类主类
{
公共静态void Main(字符串[]args)
{
使用(var session=Mapper.SessionFactory.OpenSession())
{
Console.WriteLine(“SQL生成:”);
var d=session.Get(1);
Console.ReadLine();
//Console.WriteLine(“文档的期间:”);
//foreach(d.期间中的var期间)
//{
//Console.WriteLine($“*{period.PeriodDescription}”);
//}
Console.ReadLine();
}
}
}
}
产生以下结果:

SQL produced: 
NHibernate:  
    SELECT
        document0_.Id as id1_0_1_,
        document0_.DocumentDescription as documentdescription2_0_1_,
        periods1_.DocumentId as documentid3_1_3_,
        periods1_.Id as id1_1_3_,
        periods1_.Id as id1_1_0_,
        periods1_.PeriodDescription as perioddescription2_1_0_ 
    FROM
        Document document0_ 
    left outer join
        Period periods1_ 
            on document0_.Id=periods1_.DocumentId 
    WHERE
        document0_.Id=@p0;
    @p0 = 1 [Type: Int32 (0:0:0)]
您的映射类似于以下内容。您的子集合
Lazy
-加载设置为
Lazy
(与
NoLazy
相反),但其
获取策略设置为
Join
。也就是说:

命名空间NHibernateFetchJoinTest2.DomainMapping.Mappings
{
使用NHibernate.Mapping.ByCode.Conformist;
使用NHibernateFetchJoinTest2.Domains;
公共类文档映射:类映射
{
公共文档映射()
{
Id(x=>x.Id);
属性(x=>x.DocumentDescription);
行李(x=>x.时段,收集映射=>
{
collectionMapping.Inverse(true);
Key(k=>k.Column(“DocumentId”);
Lazy(NHibernate.Mapping.ByCode.CollectionLazy.Lazy);
//删除此项。这将导致加载文档的句点,
//即使尚未访问子收集时段。
//这在SQL日志中很明显,它显示了左连接周期。
collectionMapping.Fetch(NHibernate.Mapping.ByCode.CollectionFetchMode.Join);
},mapping=>mapping.OneToMany());
}
}
公共类映射:类映射
{
公共周期映射()
{
Id(x=>x.Id);
属性(x=>x.PeriodDescription);
}
}
}
如果这是删除

collectionMapping.Fetch(NHibernate.Mapping.ByCode.CollectionFetchMode.Join);
…其父级(文档)不会过早获取子收集时段:

SQL生成:
NHibernate:
挑选
将0\u.Id记录为id1\u 0\u,
document0。DocumentDescription作为documentdescription2\u 0\u 0\u
从…起
文件0\u
哪里
document0.Id=@p0;
@p0=1[类型:Int32(0:0:0)]

使用的复制步骤:

我已经将其设置为lazy。我根本不想得到那些记录。我甚至不想从数据库中获取计数,因为会话已经不存在了。这就是为什么我不想得到那些记录。嗯。。那很危险。它可能会从表中删除子收集周期。也许即使您将子集合的
Lazy
加载策略设置为
Lazy
(或
Extra
),而不是
NonLazy
,您也已将子集合的
获取
策略设置为
加入
?因此,即使未访问子收集期间,也会获取它。查看我的新答案。它不会删除它,因为它已过期