[英]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.