EF Core 将鉴别器列添加到拥有的实体
EF Core adding discriminator column to owned entity
所以我的实体有两个属性和一个拥有的实体。出于某种原因,EF Core 正在向其中一个添加鉴别器列。如果有人能帮我弄清楚我做错了什么或者这里有什么奇怪的错误,那就太好了。
这是整个实体,尽管我怀疑只有 Requested
和 Approved
相关。
public class Absence
{
public Absence()
{
Requested = new AuditInfo();
Approved = new AuditInfo();
}
public Guid Id { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public AbsenceType Type { get; set; }
public AbsenceState State { get; set; }
public AuditInfo Requested { get; set; }
public AuditInfo Approved { get; set; }
public Guid EmployeeId { get; set; }
public Employee Employee { get; set; }
public ICollection<AbsenceDay> Days { get; set; }
}
Absence
没有任何特殊映射,但 AuditInfo 被映射为
x.Owned<AuditInfo>();
这主要生成预期的 SQL,除了这个奇怪的项目:
这也会导致代码在运行时失败并显示以下消息:
Message: Microsoft.EntityFrameworkCore.DbUpdateException : An error occurred while updating the entries. See the inner exception for details.
---- System.Data.SqlClient.SqlException : Cannot insert the value NULL into column 'ApprovedA_Discriminator', table 'bokio-test.dbo.Absences'; column does not allow nulls. INSERT fails.
The statement has been terminated.
我试过的:
我试过像这样映射项目,但没有区别:
x.Entity<Absence>().OwnsOne(x1 => x1.Approved);
x.Entity<Absence>().OwnsOne(x1 => x1.Requested);
我尝试将 Approved
重命名为 ApprovedA
,但没有任何区别。
然后我尝试了一个像这样的小重现,不会创建鉴别器列:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public Address HomeAddress { get; set; }
public Address WorkAddress { get; set; }
}
现在我没主意了,需要一些帮助。
更新 1:
请注意,事情即将变得非常奇怪!
当我将 Approved
重命名为 Donkey
时,鉴别器列消失了
最奇怪的是,当我在小测试中尝试使用名称 Approved 进行复制时,我仍然没有看到鉴别器列。
更新二:
所以我尝试了很多其他的名字。成功意味着没有鉴别器列。
Xpproved = 成功
应用=失败
Ap = 失败
CrAp = 成功
A = 失败
Axx = 成功
批准 XX = 失败
XApproved = 成功
这启发了我使用 XApproved 尝试这个解决方案,有效
x.Entity<Absence>().OwnsOne(x1 => x1.XApproved, o =>
{
o.Property(x2 => x2.Ip).HasColumnName("Approved_Ip");
o.Property(x2 => x2.UserAgent).HasColumnName("Approved_UserAgent");
o.Property(x2 => x2.UserId).HasColumnName("Approved_UserId");
o.Property(x2 => x2.TimeUtc).HasColumnName("Approved_TimeUtc");
});
更新 3:
AuditInfo 只有这些属性,除了 Owned
之外没有映射。它确实有一堆 类 继承了它:
public DateTime TimeUtc { get; set; }
public Guid? UserId { get; set; }
public string Ip { get; set; }
public string UserAgent { get; set; }
虽然我不完全理解这个问题(为什么更改名称会使问题消失),但我注意到它并没有真正解决问题。而是只是移动它。上面@philreed 的评论才是真正让它点击的原因。
AuditInfo
被另一个拥有的实体 ClosurePart
继承。通过更改
public class AuditInfo {
...props here
}
public class ClosurePart : AuditInfo {}
到
public class AuditInfoCommon {
...props here
}
public class AuditInfo : AuditInfoCommon {}
public class ClosurePart : AuditInfoCommon {}
问题完全消失了,不需要破解。
注意: AuditInfoCommon 未映射到模型中!
所以我的实体有两个属性和一个拥有的实体。出于某种原因,EF Core 正在向其中一个添加鉴别器列。如果有人能帮我弄清楚我做错了什么或者这里有什么奇怪的错误,那就太好了。
这是整个实体,尽管我怀疑只有 Requested
和 Approved
相关。
public class Absence
{
public Absence()
{
Requested = new AuditInfo();
Approved = new AuditInfo();
}
public Guid Id { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public AbsenceType Type { get; set; }
public AbsenceState State { get; set; }
public AuditInfo Requested { get; set; }
public AuditInfo Approved { get; set; }
public Guid EmployeeId { get; set; }
public Employee Employee { get; set; }
public ICollection<AbsenceDay> Days { get; set; }
}
Absence
没有任何特殊映射,但 AuditInfo 被映射为
x.Owned<AuditInfo>();
这主要生成预期的 SQL,除了这个奇怪的项目:
这也会导致代码在运行时失败并显示以下消息:
Message: Microsoft.EntityFrameworkCore.DbUpdateException : An error occurred while updating the entries. See the inner exception for details.
---- System.Data.SqlClient.SqlException : Cannot insert the value NULL into column 'ApprovedA_Discriminator', table 'bokio-test.dbo.Absences'; column does not allow nulls. INSERT fails.
The statement has been terminated.
我试过的:
我试过像这样映射项目,但没有区别:
x.Entity<Absence>().OwnsOne(x1 => x1.Approved);
x.Entity<Absence>().OwnsOne(x1 => x1.Requested);
我尝试将 Approved
重命名为 ApprovedA
,但没有任何区别。
然后我尝试了一个像这样的小重现,不会创建鉴别器列:
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
public Address HomeAddress { get; set; }
public Address WorkAddress { get; set; }
}
现在我没主意了,需要一些帮助。
更新 1:
请注意,事情即将变得非常奇怪!
当我将 Approved
重命名为 Donkey
时,鉴别器列消失了
最奇怪的是,当我在小测试中尝试使用名称 Approved 进行复制时,我仍然没有看到鉴别器列。
更新二:
所以我尝试了很多其他的名字。成功意味着没有鉴别器列。
Xpproved = 成功 应用=失败 Ap = 失败 CrAp = 成功 A = 失败 Axx = 成功 批准 XX = 失败 XApproved = 成功
这启发了我使用 XApproved 尝试这个解决方案,有效
x.Entity<Absence>().OwnsOne(x1 => x1.XApproved, o =>
{
o.Property(x2 => x2.Ip).HasColumnName("Approved_Ip");
o.Property(x2 => x2.UserAgent).HasColumnName("Approved_UserAgent");
o.Property(x2 => x2.UserId).HasColumnName("Approved_UserId");
o.Property(x2 => x2.TimeUtc).HasColumnName("Approved_TimeUtc");
});
更新 3:
AuditInfo 只有这些属性,除了 Owned
之外没有映射。它确实有一堆 类 继承了它:
public DateTime TimeUtc { get; set; }
public Guid? UserId { get; set; }
public string Ip { get; set; }
public string UserAgent { get; set; }
虽然我不完全理解这个问题(为什么更改名称会使问题消失),但我注意到它并没有真正解决问题。而是只是移动它。上面@philreed 的评论才是真正让它点击的原因。
AuditInfo
被另一个拥有的实体 ClosurePart
继承。通过更改
public class AuditInfo {
...props here
}
public class ClosurePart : AuditInfo {}
到
public class AuditInfoCommon {
...props here
}
public class AuditInfo : AuditInfoCommon {}
public class ClosurePart : AuditInfoCommon {}
问题完全消失了,不需要破解。
注意: AuditInfoCommon 未映射到模型中!