.net 对于Entityframework 3。使用数据库优先方法时,如何避免桥接表

.net 对于Entityframework 3。使用数据库优先方法时,如何避免桥接表,.net,entity-framework,.net,Entity Framework,业务案例是:发送一条带有合同列表的消息,该消息应该存储在数据库中。一个合同可以属于多个消息,一个报告可以显示与某个合同相关的消息,但这与我的代码无关。我的代码只需要存储消息,一次存储一条消息 我有3个表Message、Contract和ContractMessage。我使用模式优先(数据库优先)的方法,创建ContractMessage实体。我不需要那个实体,我只需要消息内部的List类型的属性。目前我甚至对合同中的列表都不感兴趣 我是EF的新手,听说EF1充满了麻烦。我应该保留桥牌桌吗?可以删

业务案例是:发送一条带有合同列表的消息,该消息应该存储在数据库中。一个合同可以属于多个消息,一个报告可以显示与某个合同相关的消息,但这与我的代码无关。我的代码只需要存储消息,一次存储一条消息


我有3个表Message、Contract和ContractMessage。我使用模式优先(数据库优先)的方法,创建ContractMessage实体。我不需要那个实体,我只需要消息内部的List类型的属性。目前我甚至对合同中的列表都不感兴趣


我是EF的新手,听说EF1充满了麻烦。我应该保留桥牌桌吗?可以删除桥接表并将其转换为属性,以及如何从模型中删除这些桥接表以及如何修复映射。

如果桥接表没有任何有趣的列(除了
MessageId
construct
),那么它在模型中就没有用处

您只需要
Message.Contracts
导航属性(不需要
Contract.Messages

使用模型优先的方法,只需将两个实体拖放到设计器中,并配置多对多关联:

由于您不需要
合同.消息
,只需单击导航属性并将其删除即可

从模型创建数据库架构时,Entity Framework将为您生成桥接表:

-- --------------------------------------------------
-- Creating all tables
-- --------------------------------------------------

-- Creating table 'Messages'
CREATE TABLE [dbo].[Messages] (
    [Id] int IDENTITY(1,1) NOT NULL,
    [Value] nvarchar(max)  NOT NULL
);
GO

-- Creating table 'Contracts'
CREATE TABLE [dbo].[Contracts] (
    [Id] int IDENTITY(1,1) NOT NULL,
    [Value] nvarchar(max)  NOT NULL
);
GO

-- Creating table 'MessageContract'
CREATE TABLE [dbo].[MessageContract] (
    [Messages_Id] int  NOT NULL,
    [Contracts_Id] int  NOT NULL
);
GO

-- --------------------------------------------------
-- Creating all PRIMARY KEY constraints
-- --------------------------------------------------

-- Creating primary key on [Id] in table 'Messages'
ALTER TABLE [dbo].[Messages]
ADD CONSTRAINT [PK_Messages]
    PRIMARY KEY CLUSTERED ([Id] ASC);
GO

-- Creating primary key on [Id] in table 'Contracts'
ALTER TABLE [dbo].[Contracts]
ADD CONSTRAINT [PK_Contracts]
    PRIMARY KEY CLUSTERED ([Id] ASC);
GO

-- Creating primary key on [Messages_Id], [Contracts_Id] in table 'MessageContract'
ALTER TABLE [dbo].[MessageContract]
ADD CONSTRAINT [PK_MessageContract]
    PRIMARY KEY NONCLUSTERED ([Messages_Id], [Contracts_Id] ASC);
GO

-- --------------------------------------------------
-- Creating all FOREIGN KEY constraints
-- --------------------------------------------------

-- Creating foreign key on [Messages_Id] in table 'MessageContract'
ALTER TABLE [dbo].[MessageContract]
ADD CONSTRAINT [FK_MessageContract_Message]
    FOREIGN KEY ([Messages_Id])
    REFERENCES [dbo].[Messages]
        ([Id])
    ON DELETE NO ACTION ON UPDATE NO ACTION;
GO

-- Creating foreign key on [Contracts_Id] in table 'MessageContract'
ALTER TABLE [dbo].[MessageContract]
ADD CONSTRAINT [FK_MessageContract_Contract]
    FOREIGN KEY ([Contracts_Id])
    REFERENCES [dbo].[Contracts]
        ([Id])
    ON DELETE NO ACTION ON UPDATE NO ACTION;

-- Creating non-clustered index for FOREIGN KEY 'FK_MessageContract_Contract'
CREATE INDEX [IX_FK_MessageContract_Contract]
ON [dbo].[MessageContract]
    ([Contracts_Id]);
GO

如果实体框架使用数据库优先方法将桥接表创建为实体,则通常意味着桥接表没有所需的模式,无法识别为多对多关系的桥接表,即:

  • 桥接表必须具有精确的
    (左侧实体中的主键列数)+(右侧实体中的主键列数)
    列。例如:如果左侧和右侧实体表(
    Contract
    Message
    )没有组合键,只有一个主键列,则桥接表中的列数必须正好是
    2

  • 桥接表中的所有列必须形成一个复合主键

  • 在左侧实体表的主键和桥接表中的第一列之间,必须在数据库中定义外键约束,即桥接表中的第一列是左侧实体表的外键

  • 这同样适用于右实体表和桥接表中的最后一列

  • 我不确定这一点(特别是EF 1),但可能需要启用上面提到的两个外键关系

如果满足这些规则,则不应将桥接表创建为实体。这适用于实体框架的所有版本,包括EF 1

如果其中一个需求未得到满足,EF将不会检测多对多关系并将桥接表创建为实体

这可能取决于未满足要求的细节,但通常我会说,如果不相应地更改数据库模式,就无法更改EF模型来定义工作多对多关系。例如,如果桥接表中有单独的主键列(除了左侧和右侧实体的FKs之外),则可能必须在模型中保留桥接实体


最好的解决方案是调整数据库架构,使其满足上述规则(如果您可以更改)。

“目前我甚至不想在合同中包含列表<消息>”--您的意思是不关心您是否拥有该属性,或者你的意思是你真的不想拥有那处房产?@hvd我不认为适航性是这里的主要问题。更重要的是,如果没有联接表,您无法对多对多关系进行建模,但您不一定希望该表成为C#代码中的一个实体。@hvd,是的,我不在乎是否有此属性或not@Costa通过“模式优先”,你是指MSDN文档所称的还是?@millimoose我是说数据库优先OP说他们使用的是模式优先的方法。也许他们的意思是“数据库优先”,在这种情况下,我不确定这是否回答了这个问题是的,我的问题是如何从模型中删除那些桥接表,我不知道应该如何修复映射。@millimoose我把“schema”理解为“model”。也许我错了,希望OP能澄清它的问题。@ken2k按照他们的措辞,我认为它说数据库表是创建模型的基础,但考虑到ESL的可能性,我承认这不是真正的结论。