0

In meiner Anwendung ich UserWie kann eine komplexe Eigenschaft als Bezeichner in der Entity Framework AddOrUpdate-Methode verwendet werden?

public class User 
{ 
    private ICollection<User> friends; 
    private ICollection<Album> albums; 

    public User() 
    { 
     this.albums = new HashSet<Album>(); 
     this.friends = new HashSet<User>(); 
    } 

    public int Id { get; set; } 

    public UserInfo UserInfo { get; set; } 

    public int BornTownId { get; set; } 

    public Town BornTown { get; set; } 


    public int CurrentLivingTownId { get; set; } 

    public Town CurrentLivingTown { get; set; } 

    public virtual ICollection<User> Friends 
    { 
     get 
     { 
      return this.friends; 
     } 
     set 
     { 
      this.friends = value; 
     } 
    } 

    public virtual ICollection<Album> Albums 
    { 
     get 
     { 
      return this.albums; 
     } 
     set 
     { 
      this.albums = value; 
     } 
    } 
} 

Hier haben ein Modell ist UserInfo ein komplexer Typ, die wie folgt aussieht: mit context.Users.AddOrUpdate(u => u.UserInfo.Username, user);,

[ComplexType] 
public class UserInfo 
{ 
    [Required] 
    [MaxLength(30)] 
    [MinLength(2)] 
    [Column("FirstName",TypeName = "varchar")] 
    public string FirstName { get; set; } 

    [Required] 
    [MaxLength(30)] 
    [MinLength(2)] 
    [Column("LastName", TypeName = "varchar")] 
    public string LastName { get; set; } 

    [NotMapped] 
    public string FullName => this.FirstName + " " + this.LastName; 

    [Required] 
    [MaxLength(30)] 
    [MinLength(4)] 
    [Column("Username", TypeName = "varchar")] 
    public string Username { get; set; } 

    [Required] 
    [MinLength(6)] 
    [MaxLength(50)] 
    [Column("Password", TypeName = "varchar")] 
    [PasswordValidation] 
    public string Password { get; set; } 

    [Required] 
    [Column("Email", TypeName = "varchar")] 
    [DataType(DataType.EmailAddress)] 
    [EmailValidation] 
    public string Email { get; set; } 

    [Column("RegisteredOn")] 
    public DateTime RegisteredOn { get; set; } 

    [Column("LastTimeLoggedIn")] 
    public DateTime LastTimeLoggedIn { get; set; } 

    [Range(1, 120)] 
    [Column("Age")] 
    public int Age { get; set; } 

    [Column("IsDeleted")] 
    public bool IsDeleted { get; set; } 
} 

Wenn ich versuche, Daten für die Tabelle Benutzer auf Saatgut ich erhalte die folgende Fehlermeldung:

Message=The properties expression 'u => u.UserInfo.Username' is not valid. The expression should represent a property: C#: 't => t.MyProperty'. 

Mein Quest Ion (das ist so komplex wie das Ziel des Problems) ist: Was ist die korrekte syntaktische Art, u.UserInfo.Username als Bezeichner in AddOrUpdate zu verwenden, sollte ich ein beliebiges Tag zu UserInfo Klasse oder Eigenschaft hinzufügen oder Änderungen mit der FluentApi vornehmen und was ich Ich versuche, eine ordnungsgemäße Methode zur Verwendung von AddOrUpdate zu verwenden.

Ich realisiere, dass ich Username aus UserInfo nehmen und es direkt in User setzen kann, aber ich strebe eine "breitere" Lösung an.

Jede Hilfe wird sehr geschätzt. Vielen Dank.

+0

Nur neugierig, wenn Sie AddorUpdate nicht tun, erstellt EF Spalten für die Eigenschaften Ihres komplexen Typs? – CodingYoshi

+0

@Coding Yoshi EF fügt Spalten hinzu, wenn ich AddOrUpdate das erste Mal auf diese Weise benutze, aber die Werte nicht seed, es wirft Ausnahme in nachfolgenden Seeds.Wenn ich AddOrUpdate ohne Bezeichner verwende, sät es auch die Tabelle mit den angegebenen Werten. –

Antwort

0

Die einzige Lösung, die ich ohne einfiel Username zu User Übertragung ist zunächst zu prüfen, ob ein user mit bestimmten UserInfo.Username im existiert UsersDbSet:

var user = context.Users.FirstOrDefault(u => u.UserInfo.Username == username) 
           ?? new User 
           { 
            UserInfo = new UserInfo() 
            { 
             FirstName = firstName, 
             LastName = lastName, 
             Username = username, 
             Password = password, 
             Email = email, 
             RegisteredOn = registeredOnDate.AddDays(2), 
             LastTimeLoggedIn = lastDateLoggedOn.AddDays(10), 
             IsDeleted = isDeleted 
            } 
           }; 

Dann AddOrUpdate mit dem params TEntity[] entities Überlastung verwenden, was nicht der Fall ist Verwenden Sie den "Übeltäter" System.Linq.Expressions.Expression<Func<User, object>> expression, der zu der InvalidOperationException führt.

EF aktualisiert die Werte korrekt und so funktioniert dies. Ich bin immer noch traurig, dass, während Sie Abfragen mit komplexen Typ können Sie nicht komplexen Typ in AddOrUpdate Erweiterungsmethode verwenden, um Datenbankdaten zu aktualisieren.

0

Der einzige Weg, wie Sie das zum Laufen bringen können, ist das Verschieben der Eigenschaft in die Benutzerklasse, wie Sie gesagt haben.

AddOrUpdate erfordert, dass Sie entweder eine einfache Eigenschaft des Zieltyps übergeben, um ordnungsgemäß ausgeführt zu werden, oder ein anonymes Objekt, falls Sie Ihre Entitäten mit mehr als einer Eigenschaft abgleichen möchten andere Art von Ausdruck Funktion zu ihm.

Also, ich empfehle Ihnen, Sie Username Eigenschaft auf der Benutzerklasse zu deklarieren.

Zusätzliche Hinweise: Denken Sie daran, immer Ihre komplexen Typen zu initialisieren:

public class User 
{ 
    private ICollection<User> friends; 
    private ICollection<Album> albums; 

    public User() 
    { 
     this.albums = new HashSet<Album>(); 
     this.friends = new HashSet<User>(); 

     //Good practice: always initialize your complex type properties 
     UserInfo = new UserInfo(); 
    } 

    //the rest of your class members here 
} 

hoffe, das hilft!

+0

Danke für den Hinweis. Ich weiß, dass komplexe Typen erforderlich sind, aber da ich Eigenschaften in UserInfo benötigt habe, werde ich sowieso ArgumentNullException bekommen. –

Verwandte Themen