Добавление атрибутов проверки с помощью модели данных Entity Framework
Предисловие Февраль 2015 Если вы все еще используете Entity Framework EDMX, сделайте себе одолжение и проверку, используя вместо этого Entity Framework Code First. Разница в том, что ваши таблицы создаются из ваших классов моделей, а не в EDMX, где ваши классы моделей создаются с вашими таблицами. Это решение проще, и проблема в этом вопросе даже не существует!
Начало работы с Entity Framework 6 Код Сначала с помощью MVC 5
У меня есть существующая база данных SQL, и я использую ADO.NET Enity Data Model для модели. Я пытаюсь создать некоторые функции CRUD в моем приложении MVC.
Во всех обучающих программах, которые я нашел по этому вопросу, они строят модель с нуля и добавляют атрибуты к классу модели. Например:
[Required]
[StringLength(10)]
public string Name { get; set; }
Тем не менее, классы модели автоматически генерируются, поэтому я думаю, что их изменение - плохая идея (и в любом случае все будет написано, если обновлена модель базы данных).
Как добавить атрибуты проверки?
Ответы
Ответ 1
Вы можете создать частичный класс, отдельно от созданного класса EF, для хранения метаданных.
//Contact.cs - The original auto-generated file
[System.ComponentModel.DataAnnotations.MetadataType(typeof(ContactMetadata))]
public partial class Contact
{
public int ContactID { get; set; }
public string ContactName { get; set; }
public string ContactCell { get; set; }
}
//ContactMetadata.cs - New, seperate class
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
internal sealed class ContactMetadata
{
[Required(ErrorMessage = "Name is required.")]
[StringLength(5)]
public string ContactName;
}
Ответ 2
Ответ Mason240 работает хорошо, я постараюсь его улучшить: вы можете создать новый класс ContactDataAnnotations.cs с помощью
//ContactDataAnnotations.cs - A new file
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
[MetadataType(typeof(ContactMetadata))]
public partial class Contact
{
// No field here
}
internal sealed class ContactMetadata
{
[Required(ErrorMessage = "Name is required.")]
[StringLength(5)]
public string ContactName {get; set; }
}
Таким образом, вы можете восстановить свой контактный класс через EF, не касаясь DataAnnotations - и без предупреждения, между прочим.
Ответ 3
Это уже правильно ответили, но я также хотел добавить, что я всегда находил, что вложенные метаданные казались мне более чистыми, ИМХО.
[MetadataType(typeof(ProductDescription.Metadata))]
public partial class ProductDescription
{
sealed class Metadata
{
[Key]
public long id { get; set; }
[Display(Name = "Title")]
public string title { get; set; }
// ...
}
}
Я также заметил дополнительное преимущество сохранения метаданных в классе. Атрибут будет работать только в правильном классе, предотвращая ошибку, которая может возникнуть, если вы дублируете класс (для создания аналогичного). Ошибка может возникнуть, если вы забыли изменить имя класса в атрибуте при переименовании дублированного класса.
Ответ 4
Я знаю, что это было отмечено, но я хочу очистить некоторые вещи.
@SteveCav сказал: "Этот член определен более одного раза". У меня была такая же ошибка. Проводили часы, пытаясь понять.
Чтобы, наконец, исправить это, вам нужно создать отдельный класс файлов в той же Ассамблее (я думаю, это уже упоминалось здесь). Но я хочу подчеркнуть, что этот класс должен быть вложен с частичным классом, представляющим Внутренний класс.
И тогда вы украшаете этот внутренний класс классом Annotation. Вот так:
//ContactMap.cs - Present in the same namespace as Contact.cs
[System.ComponentModel.DataAnnotations.MetadataType(typeof(ContactMap))]
partial class Contact // Present in the ContactMap class. This represent the Inner Class
{
}
//ContactMap.cs - This represent the outer class
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
public class ContactMetadata
{
[Required(ErrorMessage = "Name is required.")]
[StringLength(5)]
public string ContactName;
}
Надеюсь, что это яснее или понятнее.
Ответ 5
Здесь предлагаются варианты предлагаемых ответов, которые позволяют использовать классы в разных сборках и пространствах имен. Я на самом деле не тестировал его с помощью EF, но я использую это для классов модели API-интерфейсов Swagger.
Вкратце: наследовать от класса модели и добавлять метаданные в унаследованный класс. Дополнительным преимуществом является то, что с помощью Swagger codegen вы можете напрямую использовать модель API без сопоставления, а для начальных форм вы можете использовать защищенный по умолчанию ctor.
[MetadataType(typeof(LocalAssemblyModelMetadata))]
public class LocalAssemblyModel : IO.Swagger.Model.OtherAssemblyModel
{
public LocalAssemblyModel() : base () { }
}
public sealed class LocalAssemblyModelMetadata
{
[Required(ErrorMessage = "BaseclassProperty is mandatory.")]
public string BaseclassProperty { get; set; }
}