2011-05-28 48 views
0

为什么这段代码有效?NHibernate是否使用对象实习?

NHibernate是否采用了对象插入?

如果没有,下面的工作是因为NHibernate的重载等于运算符?

foreach (var c in s.Query<Country>()) 
{ 
    Console.WriteLine("\n{0}", c.CountryName); 

    // code in question 
    foreach(var p in s.Query<Person>().Where(x => x.Country == c)) 
     Console.WriteLine("{0}", p.PersonName); 

} 

回答

0

不能告诉NHibernate的肯定,但如果它遵循相同的规则,Hibernate的(我怀疑),它保证了在给定的会话,你可能只具有给定实体的一个实例给定的ID。这意味着如果一个国家的实例已经加载到会话中,并且如果一个人的国家拥有这个加载的实例的ID,那么该国家和该国的国家将是相同的实例,这非常合乎逻辑。

会话是一个缓存,并且在此缓存中只有一个具有给定ID的实体的实例。无需操作员超载。

+0

您的答案提示我比较不同会话中的对象。即使这两个对象来自相同的ID,但它们处于不同的会话中,它们也不共享相同的内存。所以NHibernate可以在同一会话中实习对象,但不会在不同的会话中 – Hao 2011-05-28 10:41:51

+0

这是预期的行为。会话应该表示与数据库相对较短的交互,与其他并发会话隔离。 – 2011-05-28 11:09:31

+0

这基本上是正确的,只有一点修正:会话不是缓存:它是**身份映射**(请参阅http://martinfowler.com/eaaCatalog/identityMap。html) – 2011-05-28 14:59:23

0

我想可以得到一个“假”的结论,即如果使用Linq,Hibernate正在使用对象实习。由于这是工作压力太大(即产生行):

foreach (var c in s.Query<Country>()) 
{ 
    Console.WriteLine("\n{0}'s people", c.CountryName); 

    // different memory copy 
    var cx = new Country { CountryId = 1 }; 


    foreach(var p in s.Query<Person>().Where(x => x.Country == cx)) 
     Console.WriteLine("{0}", p.PersonName); 
} 

比较对象时(实际上,事情是在DB-水平相比的NHibernate的LINQ到DB提供程序不关心实体的其他领域,不是对象),它只比较id。所以Linq到分贝以上代码,它只是东西翻译成:WHERE CountryId = 1

而如果我们预先抓取对象的内存,我们可以更容易地推断行为。这不会产生任何行,即使我们复制所有属性,因为cx指向不同的地址。所以这LINQ到内存不会产生任何行:

foreach (var c in s.Query<Country>()) 
{ 
    Console.WriteLine("\n{0}'s people", c.CountryName); 

    var cx = new Country 
    { 
     CountryId = c.CountryId, 
     CountryName = c.CountryName, 
     People = c.People.ToArray().ToList(), 
     Population = c.Population 
    }; 

    foreach(var p in s.Query<Person>().Fetch(x => x.Country) 
         .ToList().Where(x => x.Country == cx)) 
    { 
     Console.WriteLine("{0}", p.PersonName); 
    } 

} 

这里的另一个LINQ到内存代码,这一次它的各行,因此我们可以得出结论,NHibernate的实习生对象。

var china = s.Get<Country>(1); 
china.Population = 777; 

foreach (var c in s.Query<Country>()) 
{ 
    Console.WriteLine("\n{0}'s people", c.CountryName); 

    foreach(var p in s.Query<Person>().Fetch(x => x.Country) 
         .ToList().Where(x => x.Country == china)) 
    { 
     Console.WriteLine("{0} {1}", p.PersonName, p.Country.Population); 
    } 
} 

除了上面的代码中的各行,即国家中国股与使用者的国家相同的内存位置再一次证明:Person.Country.Population输出777了。所以我猜,我可以得出结论,NHibernate采用对象interning(实现方式,我认为NH有效地实现的东西,它不需要比较所有的属性时,它决定实习对象,它可以使用ID作为一个机制,whatdya认为?:-)

相关问题