繁体   English   中英

复杂类型属性如何在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);为Users表的数据设置种子时context.Users.AddOrUpdate(u => u.UserInfo.Username, user); ,我收到以下错误消息:

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

我的问题(与问题的目标一样复杂)是:在我将任何标签添加到UserInfo类或属性或使用FluentApi进行更改时,使用u.UserInfo.Username作为u.UserInfo.Username中的标识符的正确语法方法是什么FluentApi这就是我正在尝试使用AddOrUpdate的正确方法。

我意识到我可以从UserInfo中删除Username并将其直接放在User但我的目标是寻求更多的“广泛”解决方案。

任何帮助都感激不尽。 谢谢。

如您所说, UserName起作用的唯一方法是将UserName属性移到User类。

AddOrUpdate要求您传递目标类型的简单属性以正确执行,或者如果您想使用多个属性来匹配实体,则传递一个匿名对象,但是如果传递任何其他类型的表达式,它将产生抱怨功能。

因此,我建议您在User类上声明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为第一,以检查是否有user给定UserInfo.Username中存在Users 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
                                   }
                               };

然后将AddOrUpdateparams TEntity[] entities重载一起使用,该重载不使用导致InvalidOperationException的System.Linq.Expressions.Expression<Func<User, object>> expression的“罪魁祸首”。

context.Users.AddOrUpdate(user);

EF正确更新值,因此可以正常工作。 我仍然感到遗憾的是,尽管您可以使用复杂类型进行查询,但是不能在AddOrUpdate扩展方法中使用复杂类型来更新数据库数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM