如何在EF 6中映射此设计?

时间:2015-12-29 16:02:23

标签: c# entity-framework-6

我一直在摸索着如何在下面的情况下进行映射。在SQL级别上,很明显该怎么做,但在这种情况下,EF映射对我来说很有意义。

商业背景

我想存储有关区域路径如何相互关联(父 - 子)的数据,深度只有一个级别,它与您在TFS中看到的不同。

设计

我有一个表格,用于存储区域路径值,还有另一个存储关系的表格。

表,外键在SQL级别上正确设置。

CREATE TABLE [AREAPATH] (
  [ID] INT NOT NULL IDENTITY(1,1),
  [NAME] TEXT NOT NULL,
  [FULLPATH] TEXT NOT NULL)

CREATE TABLE [AREAPATH_RELATIONS](
  [ID] INT NOT NULL IDENTITY(1,1),
  [PRINCIPAL_AREAPATH_ID] INT NOT NULL,
  [DEPENDENT_AREAPATH_ID] INT NOT NULL)

在SQL中,它会产生以下数据集:

AREAPATH
ID, NAME, FULLPATH
1 , asd, asd
2 , aad, asd\aad
3 , dsa, asd\dsa

AREAPATH_RELATIONS
ID, PRINCIPAL_AREAPATH_ID, DEPENDENT_AREAPATH_ID
1 , 1                    , 2
2 , 1                    , 3
3 , 2                    , 3

我需要的数据是

  • 在SQL中有多少依赖的areapath具有所选的areapath(SELECT * FROM AREAPATH_RELATIONS WHERE PRINCIPAL_AREAPATH_ID =' givenAreaPathId')

问题

  • 我是否认为AreaPath__Id - AreaPathRelations__Principal_AreaPath_Id是一对多的关系?
  • 这个设计是否正确?我觉得它有点差,但适合目的。

更新

在对这个案例进行了一段时间的研究并看到Erik的答案后,我意识到有两个重点不够强调:

  • 孩子可以有多个父母
  • 父母可以有多个孩子

在此之后我认为AreaPath表与它自身有多对多的关系。我整理了一个映射:

modelBuilder.Entity<AreaPath>()
                .HasMany<AreaPath>(s => s.ChildAreaPathNodes)
                .WithMany(s => s.ParentAreaPathNodes)
                .Map(map =>
                {
                    map.ToTable("AREAPATH_DEPENDENCIES");
                    map.MapLeftKey("PRINCIPAL_AREAPATH_ID");
                    map.MapRightKey("DEPENDENT_AREAPATH_ID");
                });

它会抛出以下错误:

  

在模型期间检测到一个或多个验证错误   generation:\ r \ n \ r \ nAreaPathNodeAreaPathNode:Name:EntitySet   &#39; AreaPathNodeAreaPathNode&#39;使用架构&#d;&#39;和桌子   &#39; AREAPATH_DEPENDENCIES&#39;已经定义了。每个EntitySet都必须引用   到一个独特的架构和表格。

它告诉我,EF生成实体集,但由于与自身映射的表,EF希望生成两次相同的实体集。问题是我怎样才能告诉EF应该使用什么名称。可以设置吗?

AreaPath实体:

public class AreaPath
    {
        public int Id { get; set; }

        public string AreaPathName { get; set; }

        public string FullAreaPath { get; set; }

        public int AreaPathTfsId { get; set; }

        public ICollection<AreaPathNode> ChildAreaPathNodes { get; set; }

        public ICollection<AreaPathNode> ParentAreaPathNodes { get; set; }

        public int IsArchived { get; set; }
    }

1 个答案:

答案 0 :(得分:1)

如果它是一个简单的1对多(每个父母可以有多个孩子,但孩子只能有一个孩子),那么你不需要使用单独的表来建模这种关系。您只需要在AreaPath表中使用ParentId。让它可以为空,父母有空值,孩子指向父母。

这不会强制执行单个级别,但原始设计也没有。

您还应该避免使用TEXT数据类型,因为这已被弃用,并且可能会在SQL Server的未来版本中删除。相反,使用varchar(MAX)