开发者

Entity equality across different Linq-to-SQL contexts

I am attempting to add some multi-threading to a WPF application I have created in order to create a more responsive interface, but as Linq-to-SQL data contexts are not thread safe, I am forced to use one per thread.

My problem is that the same entity pulled from two different contexts, are apparently not equal. Take the following code sample, where I have a simple database with employee records:

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

var emp1 = context1.Employe开发者_如何学编程es.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();

When run, this returns:

Employees equal: False

In my mind I would expect these to objects to be equal, as they would be if I pulled them from the same context. I can overcome this by checking emp1.ID == emp2.ID instead, but this is problematic when trying to use WPF bindings such as SelectedItem.

Is there any way around this? This behaviour appears to be the same in Entity Framework as well.


Two independently instantiated objects may represent the same item in the data store, but they will never evaluate as equal in any language. You will have to write code that compares the members of each object to determine if their data is equal. This may or may not be as simple as comparing the primary key.


You can always override Equals and GetHasCode to ensure that objects are "equal" even if they are not same instance (which is default equality rule used for reference types).


As @cdonner stated, when you load an object from the data store - two different instances of the object will be created with identical data. This will mean that object1 != object2.

One way of overcoming this is to set up a cache like dictionary in your repository. Example: Dictionary<Type, object>. Where object is the type of your indentifier (int in this case).

So rather than querying the data store by using inline code like context1.Employees.Single(x => x.ID == 1); you could set it up so that you call it like Repositories.Employees.WithID(1);

What this would then do is check the local repository cache for an Employee object with ID == 1, if this is available return it instead of querying the data store.

From then on, your references will always be the same.

This may need some refining for when you want to update and\or refresh the object in memory from the data store so that you don't persist stale data, and so that when you refresh the data from the data store, you update your cache.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜