繁体   English   中英

C# 实体框架 Inheritance:自动将属性映射到子属性

[英]C# Entity Framework Inheritance: Automatic Mapping a Property To Children Property

我想知道我们是否可以在从数据库中检索时自动将 map 属性转换为子属性。

例子:

public class Account
{
    [Key]
    [Index(IsUnique = true)]
    public Guid ID { get; set; } = Guid.NewGuid();

    [Required]
    [Index(IsUnique = true)]
    [StringLength(50)]
    public string Email { get; set; }

    [Required]
    public string Password { get; set; }

    public string Hash { get; set; }

    public ICollection<Role> Roles { get; set; }

    [ForeignKey("AccountProfile")]
    public Guid? AccountProfileId { get; set; }

    public virtual AccountProfile AccountProfile { get; set; }
}

public class AccountProfile
{
    [Key]
    [Index(IsUnique = true)]
    public Guid ID { get; set; } = Guid.NewGuid();

    [Required]
    public string Name { get; set; }

    [Required]
    public string Phone { get; set; }

    public ICollection<AccountAddress> Addresses { get; set; }
}

然后我做了一个视图 model:

[NotMapped]
public class AccountVM : Account
{
    public string Name { get; set; } //Map this into AccountProfile.Name
}

从数据库中检索数据时,我想将 map Name自动转换为base.AccountProfile.Name

List<AccountVM> models = db.Accounts.Include(m => m.Roles).Include(m => m.AccountProfile).ToList();

此代码不起作用,因为我需要执行Select(m => new AccountVM() {...})这不是代码效率,因为我必须分配每个属性。

那么有没有办法做到这一点?


更新

所以我只是在我的观点 model 中发现了一点变化:

[NotMapped]
public class AccountVM : Account
{
    public string Name { get { return base.AccountProfile.Name; } set { base.AccountProfile.Name = value; } }
}

和我的猎犬:

List<AccountVM> models = db.Accounts.Include(m => m.Roles).Include(m => m.AccountProfile).Select(m => m as AccountVM).ToList();

然后出现另一个错误:

不支持具有“Yountrep.Models.Account”类型输入和“Yountrep.ViewModels.AccountVM”类型检查的“TypeAs”表达式。 LINQ 到实体查询仅支持实体类型和复杂类型。

我想现在的问题是如何将其类型转换为AccountVM

您的视图 model 不应继承自实体 model。 您可以像这样创建视图 model 以包含任何关系对象。

public class AccountVM
{
    public string Name { get; set; }
    public AccountProfile Profile { get; set; }

    public class AccountProfile
    {
        public string Name { get; set; }
    }
}

您可以在构建 LINQ 查询时手动复制属性:

List<AccountVM> vm = db.Accounts.Select(a => 
{ 
    new AccountVM {
        Name= a.Name,
        Profile = new AccountProfile {
            Name = a.AccountProfile.Name
        }    
    }
}).ToList();

另一种选择是使用 AutoMapper。 我在我的几个项目中使用 AutoMapper,它减少了手动翻译每个字段的需要。

自动映射器

如果要展平属性:

    public class AccountVM
    {
        public string Name { get; set; }
        public string ProfileName { get; set; }
    }

List<AccountVM> vm = db.Accounts.Select(a => 
{ 
    new AccountVM {
        Name= a.Name,
        ProfileName = (a.AccountProfile == null) ? "" : a.AccountProfile.Name
       }    
    }
}).ToList();

我还添加了一个三元表达式来检查 null。 如果配置文件不存在,这将避免异常错误。

暂无
暂无

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

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