模型实体框架许多加共享关系

时间:2013-04-29 07:52:49

标签: sql-server sql-server-2008 entity-framework entity-framework-5

在Entity Framework(模型优先)中,我实现了许多(例如Composition-Anthology)关系,以及必须在相关集合中匹配的附加关系(Composer)。

enter image description here

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

我目前有两个不好的想法:

糟糕的想法#1

通过在Composition和Anthology复合体上创建包含ComposerId和本地标识的主键,EF可以正确地约束它。然而,这会立即引起问题:

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

糟糕的想法#2

我可以在设计器中实现CompositionAnthology数据透视表,向其中添加ComposerId,并直接向SQL添加约束。但是这个:

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

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


编辑:我在这里通过请求发布了我的实际模型的一部分,关于我的目标可以通过不同的原理图表示来满足。 (为简洁起见,我删除了HashSet分配。)逻辑上,Composition表示此模型中的Engagement,因为必须有相关的Engagement(具有匹配的Account)才能存在认可。

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

1 个答案:

答案 0 :(得分:0)

最终,基于两个相关问题的良好数据模式反馈(以及缺乏EF反馈),我进行了很多,如上面的“糟糕的想法#2”所示。

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

有关实现的其他部分的更多详细信息,请参阅以下内容: