我有一个实体不会覆盖任何相等的成员\运算符
比较它们的两个代理(我从Nhibernate session
得到它们)时,结果会根据相等方法改变:
这更奇怪,因为它们都存在于同一会话环境中并且根据Nhibernate docs:
NHibernate只保证身份(a == b,默认值 在单个ISession中实现Equals())!`
和
该实例当前与持久性上下文相关联。它 有一个持久的身份(主键值),也许,一个 数据库中的相应行。对于特定的持久性 上下文,NHibernate保证持久标识是等价的 到CLR标识(对象的内存中位置)。
那么为什么不是所有的等式都返回true?
更新
我通过这种方式获得了enteties,查询ChildEntity的会话并使用Linq的select
获取父母实体,类似于:
var childs = session.Query<Child>();
var parents = childs.Select(x => x.ParentEntity).ToList();
答案 0 :(得分:1)
修改强>
您可能正在使用结构?见下文
我认为引用类型显示了您期望的行为:
public class Program {
class X { int x,y; }
public static void Main(string[] args)
{
X a = new X();
X b = new X();
System.Console.WriteLine(a == b);
System.Console.WriteLine(a.Equals(b));
System.Console.WriteLine(Equals(a,b));
System.Console.WriteLine(ReferenceEquals(a,b));
} }
打印:
False
False
False
False
对于结构体,事情是不同的(纪念a==b
测试,它不能为结构编译:)
public class Program {
struct X { int x,y; }
public static void Main(string[] args)
{
X a = new X();
X b = new X();
//System.Console.WriteLine(a == b);
System.Console.WriteLine(a.Equals(b));
System.Console.WriteLine(Equals(a,b));
System.Console.WriteLine(ReferenceEquals(a,b));
} }
输出:
True
True
False
Equals()的默认实现来自类ValueType
,它是所有值类型的隐式基类。您可以通过在结构中定义自己的Equals()方法来覆盖此实现。当比较不同(动态)类型的对象时,ValueType.Equals()
总是返回false。如果对象属于同一类型,会通过为每个字段调用Equals()
来比较它们。如果其中任何一个返回false,则整个过程停止,最终结果为false。如果所有逐场比较都返回true,则最终结果为真
答案 1 :(得分:0)
如果ReferenceEquals
返回false,则表明您正在比较两个不同的实例。
如果它被覆盖,则等于可能仍然是真的,但我认为这不是实际问题所在。
我想知道你是如何映射和获取这些对象的,因为正如文档所说,你永远不会得到两个相同类型的不同对象,代表同一会话中的同一行。强>
答案 2 :(得分:0)
从会话中获得childs
后,我将其与会话合并。
var childs = session.Query<Child>();
// Do some stuff
foreach (var child in childs)
{
session.Merge(child);
}
var parents = childs.Select(x => x.ParentEntity).ToList();
似乎合并将实体与会话分离,并返回附加到会话的新代理。
可以用
修复var newChild = (Child)session.Merge(child);
// Or:
session.Update(child); // (We have session.Clear() in our tests so I can't use this because it makes troubles when you update detached Entity