简体   繁体   English

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

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

I was wondering if we can automatically map a property into children property when retrieving from database.我想知道我们是否可以在从数据库中检索时自动将 map 属性转换为子属性。

Example:例子:

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; }
}

And then I make a view model:然后我做了一个视图 model:

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

I want to auto map the Name into base.AccountProfile.Name when retrieving the data from database:从数据库中检索数据时,我想将 map Name自动转换为base.AccountProfile.Name

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

This code will not work because I need to do Select(m => new AccountVM() {...}) which is not code efficient, because I have to assign each of the properties.此代码不起作用,因为我需要执行Select(m => new AccountVM() {...})这不是代码效率,因为我必须分配每个属性。

So is there a way to do this?那么有没有办法做到这一点?


Updated更新

So I just figurred out a little change in my view model into:所以我只是在我的观点 model 中发现了一点变化:

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

and my retriever:和我的猎犬:

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

Then another error arise:然后出现另一个错误:

The 'TypeAs' expression with an input of type 'Yountrep.Models.Account' and a check of type 'Yountrep.ViewModels.AccountVM' is not supported.不支持具有“Yountrep.Models.Account”类型输入和“Yountrep.ViewModels.AccountVM”类型检查的“TypeAs”表达式。 Only entity types and complex types are supported in LINQ to Entities queries. LINQ 到实体查询仅支持实体类型和复杂类型。

I guess the problem is now how to typecast it into AccountVM我想现在的问题是如何将其类型转换为AccountVM

Your view model should not be inheriting from an entity model.您的视图 model 不应继承自实体 model。 You can create your view model like this to include any relational objects.您可以像这样创建视图 model 以包含任何关系对象。

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

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

You can than manually copy over the properties when building your LINQ query:您可以在构建 LINQ 查询时手动复制属性:

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

Another alternative is to use AutoMapper.另一种选择是使用 AutoMapper。 I use AutoMapper for several of my projects, and it reduces the need to have to manually translate every field.我在我的几个项目中使用 AutoMapper,它减少了手动翻译每个字段的需要。

AutoMapper自动映射器

If you want to flatten properties:如果要展平属性:

    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();

I also added a ternary expression to check for null.我还添加了一个三元表达式来检查 null。 This will avoid an exception error if profile does not exist.如果配置文件不存在,这将避免异常错误。

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

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