it-swarm.com.de

Fügen Sie einer von Entity Framework generierten Klasse Datenanmerkungen hinzu

Ich habe die folgende Klasse von Entity Framework generiert:

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

Ich möchte dies zu einem Pflichtfeld machen

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

Da es sich jedoch um generierten Code handelt, wird dieser gelöscht. Ich kann mir keine Möglichkeit vorstellen, eine Teilklasse zu erstellen, da die Eigenschaft durch die generierte Teilklasse definiert wird. Wie kann ich die Einschränkung sicher definieren?

91
P.Brian.Mackey

Die generierte Klasse ItemRequest ist immer eine Klasse partial. Auf diese Weise können Sie eine zweite Teilklasse schreiben, die mit den erforderlichen Datenanmerkungen versehen ist. In Ihrem Fall würde die Teilklasse ItemRequest so aussehen:

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;}

        //...
    }
}
138
MUG4N

Als Antwort auf MUG4N können Sie Teilklassen verwenden, besser jedoch Schnittstellen. In diesem Fall treten Kompilierungsfehler auf, wenn das EF-Modell nicht dem Validierungsmodell entspricht. So können Sie Ihre EF-Modelle ändern, ohne befürchten zu müssen, dass die Validierungsregeln veraltet sind.

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. Wenn Sie einen Projekttyp verwenden, der sich von ASP.NET MVC unterscheidet (wenn Sie eine manuelle Datenüberprüfung durchführen), vergessen Sie nicht, Ihre Validatoren zu registrieren

/* Global.asax or similar */

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

Ich habe eine Lösung wie MUG4N gefunden, aber stattdessen die Klasse MetaData in der Entitätsklasse verschachtelt, wodurch die Anzahl der Klassen in Ihrer öffentlichen Namespace-Liste verringert und die Notwendigkeit beseitigt wurde einen eindeutigen Namen für jede Metadatenklasse haben.

using System.ComponentModel.DataAnnotations;

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

            //...
        }
    }
}
13
Carter Medlin

Dies ist eine Art Erweiterung für @dimonser answer. Wenn Sie Ihr Datenbankmodell neu generieren, müssen Sie die Schnittstellen für diese Klassen manuell neu hinzufügen.

Wenn Sie Magen dafür haben, können Sie auch Ihr .tt Vorlagen:

Hier ist ein Beispiel für die automatische Generierung von Interfaces für einige Klassen. Dies ist ein Fragment aus .tt Ersetze einfach die EntityClassOpening Methode in deiner durch folgende (und natürlich var stringsToMatch mit Ihren Entitätsnamen und Schnittstellen).

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);
}

Kein normaler Mensch sollte sich das antun, es wurde in der Bibel bewiesen, dass man dafür in die Hölle geht.

5

Ich bin nicht sicher, wie ich das tun soll, wonach Sie fragen, aber es gibt einen Ausweg. Dynamische Datenüberprüfung durch Überschreiben der GetValidators Ihres benutzerdefinierten DataAnnotationsModelValidatorProviders. Darin können Sie die Regeln für die Validierung jedes Felds (aus einer Datenbank, Konfigurationsdatei usw.) lesen und gegebenenfalls Validatoren hinzufügen. Es bietet den zusätzlichen Vorteil, dass Ihre Validierung nicht mehr eng mit dem Modell verbunden ist und geändert werden kann, ohne dass die Site neu gestartet werden muss. Natürlich könnte es für Ihren Fall übertrieben sein, aber es war ideal für unseren!

2
JTMon

Ändern Sie die T4-Vorlage, indem Sie die erforderlichen Anmerkungen hinzufügen. Diese Datei heißt normalerweise MODELNAME.tt

finden Sie heraus, wo der T4 die Klasse und die Methoden erstellt, um zu wissen, wo diese platziert werden sollen.

     <#=codeStringGenerator.IgnoreJson(navigationProperty)#>


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

            return result;
        }

Sie müssen auch die Namespaces hinzufügen.

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

Erstellen Sie Ihre Klassen neu, indem Sie Ihr Modell speichern. Alle Ihre Methoden sollten mit Anmerkungen versehen werden.

1
tswales