EntityFramework 5返回相同的对象而不是返回新对象

时间:2013-11-22 13:48:31

标签: entity-framework orm entity-framework-5

考虑以下内容......

数据库:

Table: XFUNCTION
-------------
|ID  |NAME  |
-------------
|1   |F1    |
-------------
|2   |F2    |
-------------

Table: XSYSTEM
-------------
|ID  |NAME  |
-------------
|3   |S1    |
-------------
|4   |S2    |
-------------

Table: FUNCTION_HAS_SYSTEM
--------------------------------
|ID  |SYSTEM_ID  |FUNCTION_ID  |
--------------------------------
|5   |3          |1            |
--------------------------------
|6   |3          |2            |
--------------------------------
|7   |4          |1            |
--------------------------------
|8   |4          |2            |
--------------------------------

代码:

var dbContext = new EFContext();

var functions = dbContext.XFUNCTION; //Count == 2

var systems = new List<XSYSTEM>();

foreach(var func in functions)
{
    foreach(var sys in func.systems) //Count == 2
    {
        if (!systems.Contains(sys))
                    systems.Add(sys);
    }
}

Assert.IsTrue(systems.Count == 4);

Output: systems.Count == 2 not 4

只要我没有覆盖Equals()GetHashCode()我就预计4个系统不会2 ... 有人可以告诉我为什么EF这样做,是否可以预料到?我该如何防止这种行为?

这个问题的原因是,当我尝试在其中一个函数中操作系统对象时,没有执行SaveChange()。在另一个函数中,系统对象也会发生同样的事情。我知道它们是数据库中的相同系统,但我希望它们是它们自己的对象,而不是在实体中共享。

1 个答案:

答案 0 :(得分:0)

Object.Equals()返回true,因为EF返回相同的对象! EF将查询的实体保留在内存中并默认重用,除非您禁用更改跟踪。

有许多方法可以停用更改跟踪:

1)使用.AsNoTracking()

var xfunctionSet = dbContext.XFUNCTION.AsNoTracking();
Assert.AreSame(xfunctionSet.First(), xfunctionSet.First()); //fails

2)更改MergeOption

但是如果你只想计算FUNCTION_HAS_SYSTEM中的总记录数,那就

dbContext.FUNCTION_HAS_SYSTEM.Count()