c# - 如何在 EntityFramework 中配置这种关系(1 -> many, plus 1 -> 0 or 1, no join table)
问题描述
我知道一个现实的选择是更改建议的 DB Schema;我也在追求这个选择。但是......我想知道是否可以设置 EF 以便它理解这种结构......
商业模式:
- 每个 Foo 都与一个 Bar 相关联。
- 每个 Bar 可以有多个 Foo。
- 每个 Bar 也可能有一个特殊的Foo,(尽管它可能没有)
强制“一个 Bar 的特殊 Foo 必须与那个 Bar 相关联”的一致性是代码库的责任,而不是数据库的责任。
理想情况下,执行“一个 Bar 不能有多个特殊 Foo”的一致性是数据库的责任。
选择的数据库模型:
如上所述,我知道存在其他可能的结构,它们具有许多优点(尤其是“更容易在 EF 中配置”)。
CREATE TABLE [dbo].[Foo] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[BarId] INT NOT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_Bar] FOREIGN KEY ([BarId]) REFERENCES [dbo].[Bar] ([Id])
);
CREATE TABLE [dbo].[Bar] (
[Id] INT IDENTITY (1, 1) NOT NULL,
[SpecialFooId] INT NULL,
PRIMARY KEY CLUSTERED ([Id] ASC),
CONSTRAINT [FK_SpecialFoo] FOREIGN KEY ([SpecialFooId]) REFERENCES [dbo].[Foo] ([Id])
);
领域模型的当前猜测:
public class Foo
{
public int Id { get; set; }
// Props for easy 1-many relationship.
public int BarId { get; set; }
public virtual Bar Bar { get; set; }
}
public class Bar
{
public int Id { get; set; }
// Prop for easy 1-many relationship.
public virtual ICollection<Foo> Foos { get; set; }
// Props for hard 1-0..1 relationship.
public int? SpecialFooId { get; set; }
public virtual Foo SpecialFoo { get; set; }
}
我完全不确定这个域对象模型是否适合 EF,而且我也不知道如何配置它。
有谁知道如何使这项工作?
解决方案
从根本上说,我无法完成这项工作的原因是上面描述的 DB 模型没有反映在上面描述的 C# 域对象模型中。
基于该数据库模型,单个 Foo 可能是多个Bar 的 SpecialFoo - 从 Bar 到 Foo 的 FK 不知道业务逻辑将确保实际上最多有一个 FK 指向任何给定的 Foo。
因此,类模型需要是:
public class Foo
{
public int Id { get; set; }
// Props for easy 1-many relationship.
public int BarId { get; set; }
public virtual Bar Bar { get; set; }
//****** THE CHANGED BIT ******
public ICollection<Bar> BarsForWhichThisIsTheSpecialFoo { get; set; }
//****** THE CHANGED BIT ******
}
public class Bar
{
public int Id { get; set; }
// Prop for easy 1-many relationship.
public virtual ICollection<Foo> Foos { get; set; }
// Props for hard 1-0..1 relationship.
public int? SpecialFooId { get; set; }
public virtual Foo SpecialFoo { get; set; }
}
然后正确的模型构建器咒语是:
modelBuilder.Entity<Bar>()
.HasMany(bar => bar.Foos)
.WithRequired(foo => foo.Bar)
.HasForeignKey(foo => foo.BarId);
modelBuilder.Entity<Foo>()
.HasMany(foo => foo.BarsForWhichThisIsTheSpecialFoo)
.WithOptional(bar => bar.SpecialFoo)
.HasForeignKey(bar => bar.SpecialFooId);
这表达了关系的变化 pov:根据 DB,Bars 并没有真正属于他们的 SpecialFoo ...... Foos 有一组他们是 Special 的 Bars。
推荐阅读
- javascript - 开玩笑测试失败“未定义窗口”
- node.js - Angular 无法创建新项目
- kotlin - 如何使用 spring-data-jpa 将单个列查询为单个结果值?
- sql - Excel 2007 查询编辑器 - 大于功能
- autohotkey - 热键明显滞后,如何减少延迟?
- eclipse - 缺少在 Eclipse 中安装软件的要求
- hyperledger - Sawtooth - configure-onchain-perms 问题 -
- node.js - 如何在我的服务器上配置新的 NewRelic 密钥和代码以监视创建的新帐户上的应用程序
- javascript - 无法在 Spring Security 中加载静态内容
- python - 如何通过运行我的脚本离线保存