【问题标题】:Entity equality across different Linq-to-SQL contexts跨不同 Linq-to-SQL 上下文的实体相等性
【发布时间】:2023-03-18 15:47:01
【问题描述】:

我正在尝试向我创建的 WPF 应用程序添加一些多线程,以创建响应速度更快的界面,但由于 Linq-to-SQL 数据上下文不是线程安全的,我不得不为每个线程使用一个.

我的问题是从两个不同的上下文中提取的同一个实体显然是不相等的。以下面的代码示例为例,我有一个包含员工记录的简单数据库:

var context1 = new DataModelDataContext();
var context2 = new DataModelDataContext();

var emp1 = context1.Employees.Single(x => x.ID == 1);
var emp2 = context2.Employees.Single(x => x.ID == 1);

Console.WriteLine(string.Format("Employees equal: {0}", emp1 == emp2));
Console.ReadKey();

运行时,返回:

Employees equal: False

在我看来,我希望这些对象是相等的,就像我将它们从相同的上下文中拉出来一样。我可以通过检查 emp1.ID == emp2.​​ID 来克服这个问题,但是在尝试使用诸如 SelectedItem 之类的 WPF 绑定时这是有问题的。

有没有办法解决这个问题?这种行为在 Entity Framework 中似乎也是一样的。

【问题讨论】:

    标签: c# wpf linq entity-framework linq-to-sql


    【解决方案1】:

    两个独立实例化的对象可能代表数据存储中的同一个项目,但在任何语言中它们永远不会被评估为相等。您必须编写代码来比较每个对象的成员以确定它们的数据是否相等。这可能会也可能不会像比较主键那样简单。

    【讨论】:

    • +1 只是想写同样的。操作员自己给出了答案:emp1.ID == emp2.ID 将完成这项工作(如果 ID 是唯一的主键或课程)
    • 覆盖等于似乎是要走的路
    【解决方案2】:

    您始终可以覆盖 EqualsGetHasCode 以确保对象“相等”,即使它们不是同一个实例(这是用于引用类型的默认相等规则)。

    【讨论】:

      【解决方案3】:

      正如@cdonner 所说,当您从数据存储加载对象时 - 将使用相同的数据创建该对象的两个不同实例。这将意味着 object1 != object2。

      克服此问题的一种方法是在您的存储库中设置一个类似于字典的缓存。示例:Dictionary<Type, object>object 是您的标识符的类型(在本例中为 int)

      因此,与其使用像 context1.Employees.Single(x => x.ID == 1); 这样的内联代码来查询数据存储,不如将其设置为像 Repositories.Employees.WithID(1); 这样调用它

      然后这会做的是检查本地存储库缓存中的Employee 对象与ID == 1,如果可用则返回它而不是查询数据存储。

      从那时起,您的参考资料将永远相同。

      当您想要从数据存储更新和/或刷新内存中的对象时,这可能需要一些改进,这样您就不会保留过时的数据,并且当您从数据存储刷新数据时,您更新你的缓存。

      【讨论】:

        猜你喜欢
        • 2011-04-06
        • 1970-01-01
        • 2011-07-22
        • 2023-03-11
        • 2011-04-27
        • 2011-03-25
        • 2016-08-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多