16 Stimmen

Ist es möglich zu verhindern, dass EntityFramework 4 benutzerdefinierte Eigenschaften überschreibt?

Ich verwende zunächst EF 4 Database + POCOs. Da EF keine einfache Möglichkeit hat, anzugeben, dass eingehende DateTimes vom Typ UTC sind, habe ich die Eigenschaft aus der automatisch generierten Datei in eine Teilklasse in einer anderen Datei verschoben.

    private DateTime _createdOn;
    public virtual System.DateTime CreatedOn
    {
        get { return _createdOn; }
        set
        {
            _createdOn =
                (value.Kind == DateTimeKind.Unspecified)
                    ? _createdOn = DateTime.SpecifyKind(value, DateTimeKind.Utc)
                    : value;
        }
    }

Jetzt werden jedoch jedes Mal, wenn ich das Modell aktualisiere, die automatischen Eigenschaften in der T4-Generation neu erstellt. Dies führt natürlich zu dem folgenden Kompilierungsfehler: "Der Typ 'Foo' enthält bereits eine Definition für 'CreatedOn'".

Gibt es eine Möglichkeit, EF anzuweisen, diese Eigenschaft nicht zu erzeugen und mich selbst damit umgehen zu lassen?

Update

Danke für alle Antworten...

Ich habe eine neue benutzerdefinierte Eigenschaft mit einem anderen Namen erstellt.

    public virtual System.DateTime CreatedOnUtc
    {
        get
        {
            return (CreatedOn.Kind==DateTimeKind.Unspecified)
                ? DateTime.SpecifyKind(CreatedOn, DateTimeKind.Utc)
                : CreatedOn;
        }
        set
        {
            CreatedOn =
                (value.Kind == DateTimeKind.Unspecified)
                    ? CreatedOn = DateTime.SpecifyKind(value, DateTimeKind.Utc)
                    : value;
        }
    }

Ich habe auch alle Setter und Getter der automatisch generierten Eigenschaft auf Private gesetzt, mit Ausnahme der Eigenschaften, die ich in einer Linq-to-Entities-Abfrage verwenden musste (seufz). In diesen Fällen habe ich die Getter auf intern gesetzt.

Ich wünschte, es gäbe ein Dropdown-Menü für DateTime-Typen, um festzulegen, als welche Art von DateTime EF sie behandeln soll. Das würde Stunden und die zusätzliche Komplikation gespeichert haben.

0voto

fharreau Punkte 1945

Ich weiß, dies ist eine alte Frage, aber hier ist eine Lösung, die keine Reflexion erfordert oder den DbContext für jede neue Eigenschaft zu bearbeiten.

Sie besteht in der Bearbeitung der Context.tt :

Fügen Sie zunächst das folgende using am Anfang der tt-Datei ein (etwa in Zeile 40):

using System.Data.Entity.Core.Objects;

Fügen Sie dann direkt unter dem Konstruktor (in meinem Fall etwa in Zeile 86) den folgenden Generierungscode ein:

<#
var entitiesWithDateTime = typeMapper.GetItemsToGenerate<EntityType>(itemCollection)
                                .Where(e => e.Properties.Any(p => typeMapper.GetTypeName(p.TypeUsage) == "System.DateTime"));

if(entitiesWithDateTime.Count() > 0)
{
#>
    private void ObjectMaterialized(object sender, ObjectMaterializedEventArgs e)
    {
<#
    var count = 0;
    foreach (var entityType in entitiesWithDateTime)
    {
#>
        <#=count != 0 ? "else " : String.Empty#>if(e.Entity is <#=entityType.Name#>)
        {
            var entity = e.Entity as <#=entityType.Name#>;
<#
            foreach(var property in entityType.Properties.Where(p => typeMapper.GetTypeName(p.TypeUsage) == "System.DateTime"))
            {
#>
            entity.<#=property.Name#> = DateTime.SpecifyKind(entity.<#=property.Name#>, DateTimeKind.Utc);
<#
            }
#>
        }
<#
        count++;
    }
#>
    }
<#
}
#>

Dies durchläuft zur Kompilierzeit alle Entitäten des DbContextes und ruft DateTime.SpecifyKind für jede DateTimeProperties.

Dieser Code erzeugt den gleichen Code wie michael.aird, ohne dass jede neue Eigenschaft manuell bearbeitet werden muss!

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X