2016-01-27 4 views
1

У меня есть два в моих контекстах приложения, оба равны в схеме & Структура, одна на удаленном сервере, а другая - локальный сервер, установленный на компьютере. Предполагается, что обе базы данных одинаковы, но с разными данными, я пытаюсь сделать, это получить все данные из обоих контекстов для сравнения, и поэтому я могу иметь одни и те же данные в обеих базах данных. Использование метода расширения Distinct не работает одинаково. Мой класс называется Пользователи, а их атрибуты: ID, Имя, Фамилия, Пользователь, Пароль. Поле идентификатора Identity Not null. Теперь у меня есть только идентичная запись в обеих базах данных, поэтому использование Distinct не должно возвращать данные, но я их возвращал. Я проверил хэш методом GetHashCode, и они разные. Вот мой код:Как сравнить два объекта из двух разных контекстов

foreach (var item in remote.Users) 
      lstUsers.Add(item); 
    foreach (var item in local.Users) 
      lstUsers.Add(item); 

    var results = lstUsers.Distinct().ToList(); 
+0

Не нужно сравнивать идентификатор, потому что он может быть другим. – Richard

+0

Я бы не ожидал, что это скомпилируется ... Не удаленный.Использует коллекцию другого типа, чем local.Users? Итак, как они могут быть добавлены в один список? – GendoIkari

+0

@GendoIkari: Предположительно, они одного типа, потому что схемы БД считаются идентичными. Насколько мне известно, каждый DbContext может иметь отдельный «DbSet » (хотя я его никогда не пробовал). –

ответ

0

Вы можете создать свой собственный класс бизнес-объекта для хранения пользовательской информации. Ваши lstUsers будут списком этого бизнес-объекта, а не списка типа базы данных/EF. В этом бизнес-объекте вы можете переопределить Equals и GetHashCode, чтобы сравнить только информацию, которая вам нужна, если учесть, что 2 пользовательских объекта одинаковы или нет.

private Business.User Transform(User user) 
{ 
    return new Business.User() 
    { 
     .Username = user.Username, 
     .Name = user.Name 
    }; //Etc; copy all fields you care about into your business object. 
} 

foreach (var item in remote.Users) 
     lstUsers.Add(this.Transform(item)); 
foreach (var item in local.Users) 
     lstUsers.Add(this.Transform(item)); 

var results = lstUsers.Distinct().ToList(); 
+0

Пример - это одна таблица с несколькими записями, но я должен сделать то же самое для таблиц со многими полями и записями, это сильно влияет на производительность? – Richard

+0

Он не должен иметь никакого заметного влияния на производительность вообще. Это будет иметь большое влияние на время разработки; поскольку вы создаете совершенно новый слой, чтобы отделить ваш бизнес от своей базы данных. Но при этом возникают другие преимущества, такие как большее разделение проблем; и способность создавать свою бизнес-логику и основное приложение, не завися от вашего хранилища данных. – GendoIkari

+0

и как он работает в примере набора?и как создается новый бизнес-объект? – Richard

0

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

В любом случае, поскольку каждая база данных имеет идентификатор, который является идентификатором NOT NULL, идентификатор может отличаться для объектов, которые в остальном идентичны.

Есть несколько вариантов, некоторые из которых могут быть лучше или слабее в зависимости от ваших конкретных нужд

  • Используйте UniqueID (GUID) вместо целого ID и использовать его для сравнения.
  • Добавьте уникальный идентификатор, отдельный от идентификатора к каждой записи, и используйте его для сравнения.
  • Implement IEquatable.

Я бы с осторожностью относился к overriding GetHashCode() and Equals().

+0

. Будет отсутствовать форма идентификатора поля, когда делая сравнения без влияния на производительность? – Richard

+0

Вы не можете использовать идентификатор автоматического увеличения для сравнения. Идентификатор начинается как 1 и увеличивается оттуда, отдельно в каждой базе данных. Скажем, пользователь Able добавляется в удаленную базу данных, пользователь Baker добавляется в локальную базу данных, затем вы пытаетесь синхронизировать. Able и Baker будут иметь идентификатор 1. Использование GUID для однозначной идентификации записи (либо как ключ, либо как отдельное поле (возможно, с уникальным индексом) будет достаточно быстро для многих целей. –

+0

и как использовать GUID в моем коде? Я должен изменить базу данных? – Richard