c# - 来自不同来源的 EF Core 实体继承,没有鉴别器
问题描述
我正在尝试使用 EF Core 配置下面显示的两个实体:
用户:
public class User
{
public int UserId { get; set; }
public string Title { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
[Required]
public string Email { get; set; }
[NotMapped]
public string FriendlyIdentifier
{
get
{
var name = $"{Name} {Surname}";
if (!string.IsNullOrWhiteSpace(name))
return name;
else if (!string.IsNullOrWhiteSpace(Email))
return Email;
else
return UserId.ToString();
}
}
public ICollection<Booking> Bookings { get; set; }
}
用户详情:
public class UserDetails : User
{
public DateTime? LatestBookingDate { get; set; }
}
这样做的原因是我希望能够使用他们的最新预订日期来拉取用户,而不必拉取所有预订,然后在代码中手动确定最新的预订日期。为此,我创建了一个选择最新预订日期的 SQL 视图,并且我想绑定UserDetails
到该视图。
我有以下 EF 设置:
modelBuilder.Entity<User>(builder =>
{
builder.ToTable("userdetails");
builder.HasKey(x => x.UserId);
builder.HasIndex(x => new { x.Name, x.Surname, x.Email });
});
modelBuilder.Query<UserDetails>()
.ToView("view_userdetails");
但这在尝试选择UserDetails
实体时会出现以下错误:
'不能将'User'设置为'UserDetails'的基本类型。继承层次结构不能包含实体类型和查询类型的混合。
我知道HasDiscriminator
这里描述了一个扩展:https ://docs.microsoft.com/en-us/ef/core/modeling/relational/inheritance但我并没有真正的鉴别器,因为UserDetails
它只是一个扩展User
.
我有什么办法让这个工作吗?我真的不想复制User
into的属性,UserDetails
因为当发生任何变化时,需要维护两个实体。我想保留遗产。
解决方案
我想保留遗产。
你不能(至少不是现在这样)。异常消息清楚地表明了这一点 - 它说“不能包含混合”并且没有为您提供建议。
您可以做的是将您当前的User
类成员移动到一个新的基础非实体、非查询类型类,并让User
实体和UserDetails
查询类型都继承自它,例如:
public abstract class UserInfo
{
public int UserId { get; set; }
public string Title { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
[Required]
public string Email { get; set; }
[NotMapped]
public string FriendlyIdentifier
{
get
{
var name = $"{Name} {Surname}";
if (!string.IsNullOrWhiteSpace(name))
return name;
else if (!string.IsNullOrWhiteSpace(Email))
return Email;
else
return UserId.ToString();
}
}
public ICollection<Booking> Bookings { get; set; }
}
public class User : UserInfo { }
public class UserDetails : UserInfo
{
public DateTime? LatestBookingDate { get; set; }
}
这将允许您在一个地方维护通用模型。缺点是UserDetails
无法在期望的地方使用User
,并且必须转换(尽管由于所有常见属性都相同,因此对于 AutoMapper 来说应该是微不足道的“自动”任务)。
请注意,此解决方案要求您在查询类型中Ignore
使用Bookings
导航属性:
modelBuilder.Query<UserDetails>(builder =>
{
builder.ToView("view_userdetails");
builder.Ignore(e => e.Bookings);
});
或将其移至User
实体。
推荐阅读
- javascript - ReactNative App 中的 Google Firebase 身份验证
- ios - 如何获取 SwiftUI 列表内容的高度?
- reactjs - 在 react-markdown 中添加多个换行符
- powershell - 如何将文件添加到变量 Powershell
- python - 使用python在计算机中运行程序后台时如何优化数据、内存和内存?
- typescript - 打字稿:与泛型的接口 - 在定义的对象内应用
- python - 如何从 python 字典列表值中删除字符串''?
- gekko - fstatus=1 时 MV 的 MEAS
- javascript - JS:获取顶级域名
- node.js - 如何使用 passport-saml npm 包进行单点注销 SAML?