2013-04-09 3 views
0

У меня есть много-много отношений с таблицей join в EF.Коллекция EF Hashset - переопределение равных и GetHashCode

У меня есть некоторые предложения по другим вопросам, чтобы использовать тип коллекции Hashset для отношения многих-многих и переопределять Equals() и GetHashCode().

Почему я должен использовать Hashset?

Как переопределить эти методы и что это сделать?

public class ChartQuery 
{ 
    public int ChartQueryId { get; set; } 
    public virtual ICollection<UserChartQuery> Users { get; set; } 
    ...more... 
} 

public class User 
{ 
    public int UserId { get; set; } 
    public string UserName { get; set; } 
    public virtual ICollection<UserChartQuery> SavedChartQueries { get; set; } 
    ...more... 
} 

public class UserChartQuery 
{ 
    public int UserId { get; set; } 
    public int ChartQueryId { get; set; } 

    public virtual User User { get; set; } 
    public virtual ChartQuery ChartQuery { get; set; } 

} 

ответ

1

Почему я должен использовать HashSet?

Вы не должны. Уникальность строки «многие-ко-многим» будет применяться на уровне базы данных, пока она правильно отображена. Для обеспечения его на уровне приложения практически ничего не стоит.

Как переопределить эти методы и что это сделать?

Много-ко-многим в Entity Framework не имеют различные сущности представлять отношения, так что нет никакой сущности переопределить Equals() и GetHashCode() на.

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

Update

Используя ваш пример с объектом, представляющим многие-ко-многим, это то, как вы бы реализовать Equals и GetHashCode таким образом, чтобы его можно было правильно использовать в HashSet:

public class UserChartQuery 
{ 
    public int UserId { get; set; } 
    public int ChartQueryId { get; set; } 

    public virtual User User { get; set; } 
    public virtual ChartQuery ChartQuery { get; set; } 

     protected bool Equals(UserChartQuery other) 
    { 
     return UserId == other.UserId && ChartQueryId == other.ChartQueryId; 
    } 

    public override bool Equals(object obj) 
    { 
     if (ReferenceEquals(null, obj)) return false; 
     if (ReferenceEquals(this, obj)) return true; 
     if (obj.GetType() != this.GetType()) return false; 
     return Equals((UserChartQuery) obj); 
    } 

    public override int GetHashCode() 
    { 
     unchecked 
     { 
      return (UserId*397)^ChartQueryId; 
     } 
    } 
} 

Как уже говорилось выше, я рекомендую использовать более естественный и встроенный способ сделать многие-ко-многим в EF:

public class ChartQuery 
{ 
    public int ChartQueryId { get; set; } 
    public virtual ICollection<User> Users { get; set; } 
    ...more... 
} 

public class User 
{ 
    public int UserId { get; set; } 
    public string UserName { get; set; } 
    public virtual ICollection<ChartQuery> SavedChartQueries { get; set; } 
    ...more... 
} 

В вашем картографирования, вы бы тогда определить многие-ко-многим, как таковой (в переопределения DbContext OnModelCreating):

builder.Entity<ChartQuery>() 
    .HasMany(cq => ucq.Users) 
    .WithMany(u => u.SavedChartQueries); 

В любом случае, я действительно думаю, что с помощью HashSet ненужно. Даже если сущность удовлетворяет отношения «многие ко многим», база данных будет обеспечивать уникальность составного ключа.

+0

Спасибо за ответ. «Вы можете определить сущность для удовлетворения отношений« многие ко многим »». Разве это не то, что я сделал с помощью объекта 'UserChartQuery', представляющего таблицу соединений? Если это так, я ищу пример кода, как переопределить эти методы, поскольку я не смог его найти. Если, с другой стороны, вы предлагаете мне использовать другое сопоставление без таблицы соединений, то, пожалуйста, покажите мне, как настроить такую ​​карту, потому что я боролся с этим какое-то время, пока не получил то, что хотел с помощью таблицы соединений. – parliament

+1

Да, это именно то, что вы сделали с UserChartQuery. Извините, я не заметил, что в первый раз. Я обновил ответ. Позвольте мне знать, если у вас есть еще вопросы. –

+0

Благодарим вас за обновление, щедрость за вас. Как последнее примечание, можете ли вы придумать какую-либо выгоду «на всех» для обеспечения уникальности на уровне приложения? – parliament

Смежные вопросы