如何告诉EF将我的模型放入多个表以防止冗余?

时间:2014-01-25 10:12:29

标签: c# entity-framework

我正在尝试使用EF来存储多对多关系,以便通过创建第三个表来防止冗余。但是,从我的OO角度来看,第三个表并不存在,所以我不想为它设置模型。请考虑以下设置。

public class City
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int Inhabitants { get; set; }

    public virtual ICollection<Structure> Structures { get; set; }
}

public class Structure
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int Location { get; set; }

    public virtual ICollection<City> Cities { get; set; }
}

我希望EF生成以下内容,StructureInfo作为第三个表:

CREATE TABLE [dbo].[City] (
    [ID]          INT            IDENTITY (1, 1) NOT NULL,
    [Name]        NVARCHAR (MAX) NULL,
    [Inhabitants] INT            NOT NULL
);

CREATE TABLE [dbo].[Structure] (
    [ID]   INT            IDENTITY (1, 1) NOT NULL,
    [Name] NVARCHAR (MAX) NULL,
);

CREATE TABLE [dbo].[StructureInfo] (
    [ID]           INT IDENTITY (1, 1) NOT NULL,
    [Location]     INT NOT NULL,
    [City_ID]      INT NULL,
    [Structure_ID] INT NULL,
    CONSTRAINT [FK_dbo.StructureInfo_dbo.City_City_ID] FOREIGN KEY ([City_ID]) REFERENCES [dbo].[City] ([ID]),
    CONSTRAINT [FK_dbo.StructureInfo_dbo.Structure_Structure_ID] FOREIGN KEY ([Structure_ID]) REFERENCES [dbo].[Structure] ([ID])
);

从数据库的角度来看,这似乎是正确的做法,因为Location每个城市都不同,但概念Structure可能出现在许多城市。 Location是实体City与实体Structure之间关系的属性,因此应位于单独的表中。但是,从OO的角度来看,这个单独的表没有用处,LocationStructure的特定实例的属性。我对描述这种关系的模型没兴趣。

如何告诉EF仅使用我创建的两个模型创建上述表格,以及EF在使用信息时使INNER JOIN成为必需的?

2 个答案:

答案 0 :(得分:1)

如果Location是关系的属性,则无法避免拥有关系对象。

EF将创建“在对象世界中不存在”表来管理n到n的关系,如果它只保留“关系”,但如果关系具有特定属性,则关系必须作为类型存在(和作为一个表)

即使在对象世界中,它也不是结构实例的属性,因为你说,结构可能出现在许多城市中(所以结构的一个实例可能与许多城市实例有关:所以这个实例结构不能具有位置的差异值。

所以你应该有像

这样的东西
public class City {
    public virtual ICollection<CityStructure> CityStructures {get;set;}
}

public class Structure {
    public virtual ICollection<CityStructure> CityStrucutres {get;set;}
}

public class CityStructure {
    public int Location {get;set;}
    public virtual City City {get;set;}
    public virtual Structure Structure {get;set;}
}

修改

如果您没有与该关系相关的属性,则必须存在关系表,因为您不能将“集合”存储为数据库字段。你不需要介意对象世界。

答案 1 :(得分:0)

你必须保持联想。卫星表是映射多对多的常见做法。你不需要摆脱这张桌子。