如何在 Entity Framework AddOrUpdate 方法中将复杂类型 属性 用作标识符?
How can complex type property be used as identifier in Entity Framework AddOrUpdate method?
在我的应用程序中我有一个模型 User
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;
}
}
}
在这里,UserInfo
是一个复杂类型,如下所示:
[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; }
}
当我尝试使用 context.Users.AddOrUpdate(u => u.UserInfo.Username, user);
为用户 table 播种数据时,
我收到以下错误消息:
Message=The properties expression 'u => u.UserInfo.Username' is not valid. The expression should represent a property: C#: 't => t.MyProperty'.
我的问题(和问题的目标一样复杂)是:
在 AddOrUpdate 中使用 u.UserInfo.Username
作为标识符的正确语法方法是什么,我应该将任何标记添加到 UserInfo
class 或 属性 还是使用 FluentApi
进行更改这就是我正在尝试以正确的方式使用 AddOrUpdate 的方法。
我意识到我可以从 UserInfo 中取出 Username
并将其直接放入 User
,但我的目标是获得更多 "broad" 解决方案。
任何帮助将不胜感激。谢谢。
如您所说,使它起作用的唯一方法是将 UserName
属性 移至用户 class。
AddOrUpdate
要求您传递一个简单的 属性 目标类型以便正确执行,或者传递一个匿名对象以防您想要使用多个 属性, 但如果你传递任何其他类型的表达式函数给它它会报错。
因此,我建议您在用户 class 上声明您 Username
属性。
其他建议:记住始终初始化复杂类型:
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
}
希望对您有所帮助!
在不将 Username
转移到 User
的情况下,我能想到的唯一解决方案是首先检查 Users
中是否存在给定 UserInfo.Username
的 user
] DbSet
:
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
}
};
然后使用 AddOrUpdate
和 params TEntity[] entities
重载,它不使用导致 InvalidOperationException 的 "culprit" System.Linq.Expressions.Expression<Func<User, object>> expression
。
context.Users.AddOrUpdate(user);
EF
正确地更新了值,所以这有效。
我仍然很难过,虽然您可以使用复杂类型进行查询,但您不能在 AddOrUpdate
扩展方法中使用复杂类型来更新数据库数据。
在我的应用程序中我有一个模型 User
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;
}
}
}
在这里,UserInfo
是一个复杂类型,如下所示:
[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; }
}
当我尝试使用 context.Users.AddOrUpdate(u => u.UserInfo.Username, user);
为用户 table 播种数据时,
我收到以下错误消息:
Message=The properties expression 'u => u.UserInfo.Username' is not valid. The expression should represent a property: C#: 't => t.MyProperty'.
我的问题(和问题的目标一样复杂)是:
在 AddOrUpdate 中使用 u.UserInfo.Username
作为标识符的正确语法方法是什么,我应该将任何标记添加到 UserInfo
class 或 属性 还是使用 FluentApi
进行更改这就是我正在尝试以正确的方式使用 AddOrUpdate 的方法。
我意识到我可以从 UserInfo 中取出 Username
并将其直接放入 User
,但我的目标是获得更多 "broad" 解决方案。
任何帮助将不胜感激。谢谢。
如您所说,使它起作用的唯一方法是将 UserName
属性 移至用户 class。
AddOrUpdate
要求您传递一个简单的 属性 目标类型以便正确执行,或者传递一个匿名对象以防您想要使用多个 属性, 但如果你传递任何其他类型的表达式函数给它它会报错。
因此,我建议您在用户 class 上声明您 Username
属性。
其他建议:记住始终初始化复杂类型:
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
}
希望对您有所帮助!
在不将 Username
转移到 User
的情况下,我能想到的唯一解决方案是首先检查 Users
中是否存在给定 UserInfo.Username
的 user
] DbSet
:
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
}
};
然后使用 AddOrUpdate
和 params TEntity[] entities
重载,它不使用导致 InvalidOperationException 的 "culprit" System.Linq.Expressions.Expression<Func<User, object>> expression
。
context.Users.AddOrUpdate(user);
EF
正确地更新了值,所以这有效。
我仍然很难过,虽然您可以使用复杂类型进行查询,但您不能在 AddOrUpdate
扩展方法中使用复杂类型来更新数据库数据。