Уникальный множественный столбец в EF6 codefirst

У меня есть электронная почта класса, которая выглядит так:

public class Email
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    public string Subject { get; set; }
    public string Body { get; set; }
    public string From { get; set; }
    public DateTime SentOn { get; set; }
    public List<string> To { get; set; }
}

Для обеспечения уникальности я сделал составной ключ на Subject, From и SentOn

Это создало проблему, заключающуюся в том, что, когда длина темы превышает 128 символов, проверка завершается ошибкой. Поэтому я просто добавил к нему атрибут [MaxLength]. Но теперь это не может быть ключевой столбец

Что я должен делать? Есть ли способ обеспечить уникальность, не будучи ключом?


person WindowsMaker    schedule 17.10.2014    source источник
comment
Я могу отправить два разных письма с одной и той же темой. Если SentOn имеет миллисекундную точность, то From и SentOn должно быть достаточно.   -  person Gert Arnold    schedule 18.10.2014
comment
И From не должен быть NVarChar(MAX)   -  person Chris Moschini    schedule 04.03.2016


Ответы (2)


Если вы используете EF 6.1, вы можете использовать многостолбцовые индексы. характерная черта:

public class Email
{
   [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
   public int Id { get; set; }
   [Index("IX_EmailUniqueness", 1, IsUnique = true)]
   public string Subject { get; set; }
   public string Body { get; set; }
   [Index("IX_EmailUniqueness", 2, IsUnique = true)]
   public string From { get; set; }
   [Index("IX_EmailUniqueness", 3, IsUnique = true)]
   public DateTime SentOn { get; set; }
   public List<string> To { get; set; }
}
person Masoud    schedule 18.10.2014
comment
Сделал это и в моем случае, но когда я сгенерировал начальную конфигурацию (Add-Migration), метод Up() миграции сгенерировал индекс только для первого столбца: .Index(t => t.XXXXX, unique=true, имя: ÏX_XXXX) - person Lord of Scripts; 11.06.2015
comment
Когда я сделал это для свойства/столбца, которое было строкой, EF выдает следующую ошибку: Столбец «Электронная почта» в таблице «dbo.Patients» имеет тип, который недопустим для использования в качестве ключевого столбца в индексе. - person TravisO; 01.06.2017

Ознакомьтесь с этим сообщением SO здесь, вы можете добавить индекс для обеспечения уникальности либо в качестве атрибута, либо с помощью EF FluentAPI Установка уникального ограничения с помощью Fluent API?

Обратите внимание, что вы должны использовать EF6.1 или более позднюю версию. Вот статья MSDN

ИЗМЕНИТЬ:

После проверки здесь и msdn немного, и похоже, что существует ограничение на ключи PK и индекса, равные 900 байтам или меньше, поэтому вы захотите использовать свою личность в качестве ключа и обеспечить уникальность другим способом.

Например, я попытался вручную создать столбец темы как уникальный с длиной 4000 и получил эту ошибку:

Warning! The maximum key length is 900 bytes. The index 'UQ__Emails__A2B1D9048E9A2A16' has maximum length of 8000 bytes. For some combination of large values, the insert/update operation will fail. и если бы вы использовали параметр кластеризованного ключа, вы бы получили это предупреждение при создании (и я сделал длину 4000 для каждого столбца) Warning! The maximum key length is 900 bytes. The index 'PK_dbo.Emails' has maximum length of 16012 bytes. For some combination of large values, the insert/update operation will fail. что на самом деле означает, что почти все записи в реальном мире не будут работать.

Таким образом, хотя вы можете вручную обойти ограничение длины 128, это не рекомендуется, и вы, скорее всего, получите ошибки и потерянные данные. и EF позволит вам иметь длину ключа только 128 - не уверен, что он будет делать, если вы пойдете за ним и измените это.

person tophallen    schedule 17.10.2014
comment
он по-прежнему жалуется на то, что не может быть ключевым столбцом :( - person WindowsMaker; 18.10.2014
comment
один из вариантов обеспечения уникальности - получить хэш свойств, которые вы хотите оставить уникальными, и использовать его как уникальный столбец - или (менее эффективно) проверить коллекцию перед сохранением. - person tophallen; 18.10.2014