Равенство сущностей в разных контекстах Linq-to-SQL - PullRequest
3 голосов
/ 08 сентября 2011

Я пытаюсь добавить многопоточность в созданное мною приложение 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 , но это проблематично при попытке использовать привязки WPF, такие как SelectedItem .

Есть ли способ обойти это? Такое поведение, по-видимому, одинаково и в Entity Framework.

Ответы [ 3 ]

2 голосов
/ 08 сентября 2011

Два независимо созданных объекта могут представлять один и тот же элемент в хранилище данных, но они никогда не будут оцениваться как равные на любом языке. Вам нужно будет написать код, который сравнивает элементы каждого объекта, чтобы определить, равны ли их данные. Это может или не может быть так просто, как сравнение первичного ключа.

1 голос
/ 08 сентября 2011

Вы всегда можете переопределить Equals и GetHasCode, чтобы гарантировать, что объекты "равны", даже если они не являются одним и тем же экземпляром (это правило равенства по умолчанию, используемое для ссылочных типов).

0 голосов
/ 08 сентября 2011

Как сказал @cdonner, когда вы загружаете объект из хранилища данных - два разных экземпляра объекта будут созданы с одинаковыми данными.Это будет означать, что object1! = Object2.

Одним из способов преодоления этого является установка кеш-подобного словаря в вашем хранилище.Пример: Dictionary<Type, object>. Где object - это тип вашего идентификатора (в данном случае int) .

Поэтому вместо того, чтобы запрашивать хранилище данных с помощью встроенного кода, например context1.Employees.Single(x => x.ID == 1);, вы можете настроить его такчто вы называете это как Repositories.Employees.WithID(1);

Затем это будет проверять кэш локального хранилища для объекта Employee с ID == 1, если он доступен, вернуть его вместо запроса к хранилищу данных.

С этого момента ваши ссылки всегда будут одинаковыми.

Это может потребовать некоторого уточнения, когда вы хотите обновить и \ или обновить объект в памяти из хранилища данных, чтобы высохраняются устаревшие данные, и поэтому при обновлении данных из хранилища данных вы обновляете кэш.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...