Подтвердить что ты не робот

Добавление атрибутов проверки с помощью модели данных 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; }

Тем не менее, классы модели автоматически генерируются, поэтому я думаю, что их изменение - плохая идея (и в любом случае все будет написано, если обновлена ​​модель базы данных).

Как добавить атрибуты проверки?

4b9b3361

Ответ 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; }
}