EF6 FluentAPI,0:1 单向
Posted
技术标签:
【中文标题】EF6 FluentAPI,0:1 单向【英文标题】:EF6 FluentAPI, 0:1 Unidirectional 【发布时间】:2017-03-01 09:48:10 【问题描述】:过去三个小时我一直在试图解决这个问题,最后放弃了(我会解决它)。但是...只是为了确定...有没有办法在 EF6 Fluent API 中设置单向 0:1/1:1?
考虑:
CREATE TABLE LegacyUsers (
ID INT NOT NULL PRIMARY KEY,
UserName NVARCHAR(50),
EmployeeID INT NULL
)
CREATE TABLE Employees (
ID INT NOT NULL PRIMARY KEY,
EmployeeName NVARCHAR(50)
)
领域模型:
public class LegacyUser
public int ID get;set;
public int? EmployeeID get;set;
public virtual Employee Employee get;set;
public class Employee
public int ID get;set;
public string EmployeeName get;set;
“Fluent”(哈哈)API理论设置:
modelBuilder.Entity<LegacyUser>()
.HasOptional(x => x.Employee)
.WithForgeignKey(x => x.EmployeeID)
我已经研究了几个小时,并尝试了许多方法来配置它。对于我的努力,我得到了“列名已经存在”验证错误或“无效列:Employee_ID”错误的回报(如果这是双向的,我可以很容易地修复这些错误,但这或多或少是一个锁定模式)。我发现唯一会迫使它工作的是将其作为 1:M 关系进行尝试,这会因为必须将域模型属性用作集合而不是简单的单一的属性。
真的没有办法像我认为的那样简单吗?要求非常简单:在给定旧用户文件中的员工 ID 的情况下获取关联的员工对象(无需破坏模型或向数据库添加新字段)
(供参考):
One to zero-or-one with HasForeignKey
Unidirectional One-To-One relationship in Entity Framework
【问题讨论】:
【参考方案1】:我发现唯一会迫使它工作的事情是将其作为 1:M 关系进行尝试,这会因为必须将域模型属性用作集合而不是简单的单一属性。
这确实是设置Associations in EF Code First: Part 5 – One-to-One Foreign Key Associations 中描述的这种关系的唯一方法。但是您误读了单向部分。幸运的是,“uni”部分是依赖端的单个导航属性 - 正是外键属性所在的位置。
所以你的模型没问题,你只需要这样设置:
modelBuilder.Entity<LegacyUser>()
.HasOptional(e => e.Employee)
.WithMany()
.HasForeignKey(e => e.EmployeeID)
.WillCascadeOnDelete(false);
最重要的部分是无参数的WithMany
调用。
【讨论】:
谢谢,但除非我遗漏了什么,否则仍会强制域属性作为集合而不是单个属性公开。如果有一种方法我可以将该集合 only 暴露给 EF 项目而不是消费项目,我可以在它周围放置一个包装器属性来获取 FirstOrDefault() 以用于“实际”域消费,但我不要认为那可以做到。不过我会环顾四周。 你在说什么域集合属性?我在域模型中没有看到这样的,你呢? 为了使用WithMany()
,我的public virtual Employee Employee get;set;
需要是ICollection<Employee>
类型而不是单个Employee 实例(除非我遗漏了什么......这是我遇到的问题早先尝试这种方法时)
不,它没有。不要碰您的域模型类,只需使用答案中的流畅配置即可。
好吧!我很高兴我问了。对不起,我确实遗漏了一些东西 - 我不确定那可能是什么,但正如你所描述的那样再次运行它确实可以按我的意愿工作。非常感谢!以上是关于EF6 FluentAPI,0:1 单向的主要内容,如果未能解决你的问题,请参考以下文章
Oracle 11G GoldenGate实现Windows与Windows之间的单向同步