1

在实体框架(模型优先)中,我正在实现一个多对多(例如Composition-Anthology)关系,以及一个必须在相关集中匹配的附加关系(Composer)。

在此处输入图像描述

如何在 EF 中正确创建此模型?

我目前有两个坏主意:

坏主意#1

通过在 Composition 和 Anthology 组合上创建主键,同时包含 ComposerId 和本地标识,EF 正确地限制了这一点。然而,这会导致直接的问题:

  • 所有与 Composition 和 Anthology 相关的表现在也具有 FK 的 ComposerId;DBA 很痛苦。
  • 我不能仅根据唯一身份等使用 EF 5.0 的 EntitySet.Find()。

坏主意#2

我可以在设计器中具体化 CompositionAnthology 数据透视表,将 ComposerId 添加到其中,然后将约束直接添加到 SQL。然而这:

  • 中断 EF 数据库创建/更新
  • 打破实体导航/添加

注意:我的数据实际上模拟了一个不那么直观的“参与”模型,但这个比喻很有效。


编辑:我根据要求在此处发布了我的实际模型的一部分,希望我的目标可以通过不同的示意图表示来实现。(为简洁起见,我删除了 HashSet 分配。)逻辑上,Composition 表示此模型中的 Engagement,因为必须存在相关的 Engagement(具有匹配的 Account)才能存在 Endorsement。

public partial class Account
{
    public int Id { get; set; }
    public string PrimaryEmail { get; set; }

    public virtual ICollection<Endorsement> EndorsementsGiven { get; set; }
    public virtual ICollection<Endorsement> EndorsementsReceived { get; set; }
    public virtual ICollection<Engagement> Engagements { get; set; }
    public virtual ICollection<EngagementEndorsement> EngagementEndorsements { get; set; }
}

public partial class EngagementEndorsement
{
    public int Endorsement_Id { get; set; }
    public int Engagement_Id { get; set; }
    public int Account_Id { get; set; }

    public virtual Endorsement Endorsement { get; set; }
    public virtual Engagement Engagement { get; set; }
    public virtual Account Account { get; set; }
}

public partial class Engagement
{
    public int Id { get; set; }
    public System.DateTime Start { get; set; }
    public System.DateTime End { get; set; }
    public string JobFunction { get; set; }

    public virtual Account Account { get; set; }
    public virtual ICollection<EngagementEndorsement> EngagementEndorsements { get; set; }
}

public partial class Endorsement
{
    public int Id { get; set; }
    public EndorsementStatus Status { get; set; }
    public EndorserRole EndorserRole { get; set; }
    public string Note { get; set; }

    public virtual Account Endorsee { get; set; }
    public virtual Account Endorser { get; set; }
    public virtual ICollection<EngagementEndorsement> EngagementEndorsements { get; set; }
}

我目前正在做“坏主意 #2”(见上文) - 创建数据库后,我应用其他关系/约束:

-- --------------------------------------------------
-- Ensure Engagement-to-Endorsement AccountId match
-- --------------------------------------------------

ALTER TABLE [dbo].[Engagements]
ADD CONSTRAINT [UK_EngagementIdAccountId]
    UNIQUE NONCLUSTERED
        ([Id], [Account_Id])
    WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

ALTER TABLE [dbo].[EngagementEndorsements]
ADD CONSTRAINT [FK_EngagementIdAccountId]
    FOREIGN KEY ([Engagement_Id], [Account_Id])
    REFERENCES [dbo].[Engagements]
        ([Id], [Account_Id])
    ON DELETE NO ACTION ON UPDATE NO ACTION;

ALTER TABLE [dbo].[Endorsements]
ADD CONSTRAINT [UK_EndorsementIdAccountId]
    UNIQUE NONCLUSTERED
        ([Id], [Endorsee_Id])
    WITH( STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]

ALTER TABLE [dbo].[EngagementEndorsements]
ADD CONSTRAINT [FK_EndorsementIdAccountId]
    FOREIGN KEY ([Endorsement_Id], [Account_Id])
    REFERENCES [dbo].[Endorsements]
        ([Id], [Endorsee_Id])
    ON DELETE NO ACTION ON UPDATE NO ACTION;
GO
4

1 回答 1

0

最终,基于两个相关问题中良好的数据模式反馈(以及缺乏 EF 反馈),我按照上面“坏主意 #2”中所示的方式进行了非常多的操作。

我一直在使用它,它满足了我当前的所有需求。

有关实现的其他位的更多详细信息,请参阅这些:

于 2013-05-08T13:29:26.380 回答