2

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

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

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

4

2 回答 2

0

如果您的桥接表没有任何有趣的列(除了MessageIdand之外ContractId),那么它在您的模型中就没有用了。

而且您只想Message.Contracts导航属性(您不需要Contract.Messages)。

使用 Model First 方法,只需将 2 个实体拖放到设计器并配置多对多关联

在此处输入图像描述

由于您不需要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
于 2013-07-12T17:53:37.580 回答
0

如果 Entity Framework 将桥表创建为具有数据库优先方法的实体,则通常意味着桥表没有被识别为多对多关系的桥表所需的架构 - 即:

  • 桥接表必须具有精确 (number of primary key columns in left entity) + (number of primary key columns in right entity)的列。例如:如果你的左右实体表(ContractMessage)没有复合键,只有一个主键列,桥表中的列数必须正好 2

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

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

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

  • 我不确定这一点(尤其是对于 EF 1),但可能需要上面提到的两个外键关系必须启用级联删除。

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

如果不满足这些要求之一,EF 将不会检测多对多关系并将桥表创建为实体。

这可能取决于未满足要求的细节,但通常我会说您无法更改 EF 模型来定义有效的多对多关系,而无需相应地更改数据库架构。例如,如果您在桥表中有一个单独的主键列(除了左右实体的 FK),您可能必须在模型中保留桥实体。

最好的解决方案是调整数据库模式,使其满足上述规则——如果你可以改变它。

于 2013-07-14T13:45:13.227 回答