Добавление аннотаций данных в класс, созданный Entity framework


у меня есть следующий класс, созданный Entity framework:

public partial class ItemRequest
{
    public int RequestId { get; set; }
    //...

Я хотел бы сделать это обязательным полем

[Required]
public int RequestId { get;set; }

однако, поскольку это сгенерированный код, это будет уничтожено. Я не могу представить себе способ создания частичного класса, потому что свойство определяется сгенерированным частичным классом. Как я могу определить ограничение безопасным способом?

6 89

6 ответов:

созданный класс ItemRequest всегда будет partial класса. Это позволяет написать второй частичный класс, который помечен необходимыми аннотациями данных. В вашем случае частичный класс ItemRequest будет выглядеть так:

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

//make sure the namespace is equal to the other partial class ItemRequest
namespace MvcApplication1.Models 
{
    [MetadataType(typeof(ItemRequestMetaData))]
    public partial class ItemRequest
    {
    }

    public class ItemRequestMetaData
    {
        [Required]
        public int RequestId {get;set;}

        //...
    }
}

Как MUG4N ответ вы можете использовать частичные классы но будет лучше использовать интерфейсы. В этом случае у вас будут ошибки компиляции, если модель EF не соответствует модели проверки. Таким образом, вы можете изменить свои модели EF, не опасаясь, что правила проверки устарели.

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;

namespace YourApplication.Models
{
    public interface IEntityMetadata
    {
        [Required]
        Int32 Id { get; set; }
    }

    [MetadataType(typeof(IEntityMetadata))]
    public partial class Entity : IEntityMetadata
    {
        /* Id property has already existed in the mapped class */
    }
}

P. S. Если вы используете тип проекта, который отличаются от ASP.NET MVC-фреймворков (при выполнении ручной проверки данных) не забудьте зарегистрировать валидаторы

/* Global.asax or similar */

TypeDescriptor.AddProviderTransparent(
    new AssociatedMetadataTypeTypeDescriptionProvider(typeof(Entity), typeof(IEntityMetadata)), typeof(Entity));

Я нашел решение, как MUG4N ответ, но вместо этого, вложив MetaData класс в классе сущностей, тем самым уменьшая количество классов в списке общедоступных пространств имен и устраняя необходимость иметь уникальное имя для каждого класса метаданных.

using System.ComponentModel.DataAnnotations;

namespace MvcApplication1.Models 
{
    [MetadataType(typeof(MetaData))]
    public partial class ItemRequest
    {
        public class MetaData
        {
            [Required]
            public int RequestId;

            //...
        }
    }
}

Это своего рода расширение для ответа @dimonser если вы регенерируете свою модель БД, вам придется вручную повторно добавить интерфейсы в эти классы.

если у вас есть желудок для этого вы также можете изменить свой .tt шаблоны:

вот из автоматической генерации интерфейсов на некоторые классы, это фрагмент из .tt просто заменить EntityClassOpening метод в вашем со следующим (и очевидно var stringsToMatch С вашими именами сущностей и интерфейсов).
public string EntityClassOpening(EntityType entity)
{
    var stringsToMatch = new Dictionary<string,string> { { "Answer", "IJourneyAnswer" }, { "Fee", "ILegalFee" } };
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1}partial class {2}{3}{4}",
        Accessibility.ForType(entity),
        _code.SpaceAfter(_code.AbstractOption(entity)),
        _code.Escape(entity),
        _code.StringBefore(" : ", _typeMapper.GetTypeName(entity.BaseType)),
        stringsToMatch.Any(o => _code.Escape(entity).Contains(o.Key)) ? " : " + stringsToMatch.Single(o => _code.Escape(entity).Contains(o.Key)).Value : string.Empty);
}

нет нормальный человек должен сделать это для себя, хотя, это было доказано в Библии, что один идет в ад для этого.

Я не уверен, как сделать то, что вы просите, но есть способ обойти это. Динамическая проверка данных путем переопределения GetValidators пользовательского DataAnnotationsModelValidatorProvider. В нем вы можете прочитать правила проверки каждого поля (из базы данных, конфигурационного файла и т. д.) и добавить валидаторы по мере необходимости. Он имеет дополнительные значения, что ваша проверка больше не тесно связана с моделью и может быть изменена без необходимости даже перезапуска сайта. Конечно, это может быть перебор для вашего случая, но это было идеально для нас!

изменить шаблон T4 добавление необходимых аннотаций, этот файл обычно называется MODELNAME.tt

найти, где T4 создает класс и методы, чтобы знать, где их разместить.

     <#=codeStringGenerator.IgnoreJson(navigationProperty)#>


//create this method in file
public string IgnoreJson(NavigationProperty navigationProperty){
            string result = navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.Many ? "" : @"[JsonIgnore]
    [IgnoreDataMember]";

            return result;
        }

вам также нужно будет добавить пространства имен;

<#=codeStringGenerator.UsingDirectives(inHeader: false)#>
using System.ComponentModel.DataAnnotations;
using Newtonsoft.Json;
using System.Runtime.Serialization;

перестроить классы, сохранив модель, все ваши методы должны быть аннотированы.