Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 关系上的条件映射_C#_.net_Entity Framework_Ef Code First_Entity Framework 5 - Fatal编程技术网

C# 关系上的条件映射

C# 关系上的条件映射,c#,.net,entity-framework,ef-code-first,entity-framework-5,C#,.net,Entity Framework,Ef Code First,Entity Framework 5,使用实体框架(代码优先),我尝试在以下两个实体之间映射条件/过滤关系: 建筑 BuildingId 建筑名称 区域 区域ID ParentId 区域名称 IsSubArea 建筑可以有许多区域 一个区域可以有许多(子)区域 我想在建筑和区域之间创建关系,其中标记为“Isubera”的区域将从关系中筛选出来。在此上下文中,ParentId将与建筑相关,否则ParentId将是另一个区域。这将允许我创建一个有许多区域的建筑,每个区域可以有许多子区域,创建一个树状结构 我找到的最接近解决方案涉及“软删

使用实体框架(代码优先),我尝试在以下两个实体之间映射条件/过滤关系:

建筑
BuildingId
建筑名称

区域
区域ID
ParentId
区域名称
IsSubArea

建筑可以有许多区域
一个区域可以有许多(子)区域

我想在建筑区域之间创建关系,其中标记为“Isubera”的区域将从关系中筛选出来。在此上下文中,ParentId将与建筑相关,否则ParentId将是另一个区域。这将允许我创建一个有许多区域的建筑,每个区域可以有许多子区域,创建一个树状结构

我找到的最接近解决方案涉及“软删除”功能():

然后我有以下两种EntityTypeConfiguration:

public class BuildingAreaMap : EntityTypeConfiguration<BuildingArea>
{
    public BuildingAreaMap ()
    {
        // Primary Key
        HasKey(t => t.AreaId);

        // Properties
        Property(t => t.AreaName)
            .IsRequired()
            .HasMaxLength(256);

        // Table & Column Mappings 
        ToTable("Areas");
        Property(t => t.AreaId).HasColumnName("AreaId");
        Property(t => t.ParentId).HasColumnName("ParentId");
        Property(t => t.AreaName).HasColumnName("AreaName");
        Property(t => t.IsSubArea).HasColumnName("IsSubArea");

        // This is the discriminator column
        Map(m => m.Requires("IsSubArea").HasValue(false));

        HasRequired(a => a.Site).WithMany(s => s.SiteAreas).HasForeignKey(k => k.ParentId);
    }


public class SubAreaMap : EntityTypeConfiguration<SubArea>
{
    public SubAreaMap()
    {
        // Primary Key
        HasKey(t => t.AreaId);

        // Properties
        Property(t => t.AreaName)
            .IsRequired()
            .HasMaxLength(256);

        // Table & Column Mappings 
        ToTable("AssetHealthAreas");
        Property(t => t.AreaId).HasColumnName("AreaId");
        Property(t => t.ParentId).HasColumnName("ParentId");
        Property(t => t.AreaName).HasColumnName("AreaName");
        Property(t => t.IsSubArea).HasColumnName("IsSubArea");

        // This is the discriminator column
        Map(m => m.Requires("IsSubArea").HasValue(true));

        HasRequired(a => a.Parent).WithMany(s => s.SubAreas).HasForeignKey(k => k.ParentId);
    }
}
这也给了我同样的错误

如果我从等式中删除关系,我会得到一个关于
ParentId
属性的不同错误:

外键组件“ParentId”不是类型“SiteArea”上声明的属性。验证它是否未被明确地从模型中排除,并且它是一个有效的基元属性。

更新3

我试图创建的模型的图像

更新4

我将尝试简化我的模型以匹配以下内容。 如果下面的解决方案有效,我将需要更多的业务逻辑来导航树,但它应该是可管理的


有关创建TPH类时的错误: 我认为这是因为在类中不应该将discriminator列作为属性

从基类中删除属性Isubera


当您创建新实例时,EF应自动检测类型并相应地填写Isubera。

这也是一个很好的参考:@Colin谢谢,是的,我在写问题后也发现了这一点。我现在正在努力。另一个堆积如山的问题或多或少是你想要什么。。但没有干净的解决方案。我希望下一个EF版本中会包含类似的内容…@Tsasken谢谢,我很快就会阅读。其中之一是您需要映射基本类型(
区域
)。这可以是类似于子类型之一的映射。然后在子类型映射中,只映射特定于子类型的内容。此外,由于所有内容都在一个表中,
ParentId
必须为空。
modelBuilder.Entity<Area>().Map(m => m.Requires("IsSubArea").HasValue(false));
public class Building
{
    public int BuildingId {get; set;}
    public string BuildingName {get; set;}

    public IQueryable<Area> BuildingAreas
    {
        get 
        {
            return from area in areas
                   where area.IsSubArea == false
                   and   area.ParentId == BuildingId
                   select area;

            //Assume I have a reference to relevant DbSets
        }
    }
}
public abstract class Area
{
    protected Area(bool isSubArea)
    {
        IsSubArea = isSubArea;
        SubAreas = new List<SubArea>();
    }

    public int AreaId { get; set; }
    public int ParentId { get; set; }
    public string AreaName { get; set; }
    public bool IsSubArea { get; private set; } //note the private set

    public virtual ICollection<SubArea> SubAreas { get; set; }
}
public class BuildingArea : Area
{
    public BuildingArea () : base(false)
    {}

    public virtual Building ParentBuilding { get; set; }        
}

public class SubArea : Area
{
    public SubArea(): base(true)
    {}

    // This is of type `Area` because parent could be either `BuildingArea` or `SubArea`
    public virtual Area Parent { get; set; }        
}
public class BuildingAreaMap : EntityTypeConfiguration<BuildingArea>
{
    public BuildingAreaMap ()
    {
        // Primary Key
        HasKey(t => t.AreaId);

        // Properties
        Property(t => t.AreaName)
            .IsRequired()
            .HasMaxLength(256);

        // Table & Column Mappings 
        ToTable("Areas");
        Property(t => t.AreaId).HasColumnName("AreaId");
        Property(t => t.ParentId).HasColumnName("ParentId");
        Property(t => t.AreaName).HasColumnName("AreaName");
        Property(t => t.IsSubArea).HasColumnName("IsSubArea");

        // This is the discriminator column
        Map(m => m.Requires("IsSubArea").HasValue(false));

        HasRequired(a => a.Site).WithMany(s => s.SiteAreas).HasForeignKey(k => k.ParentId);
    }


public class SubAreaMap : EntityTypeConfiguration<SubArea>
{
    public SubAreaMap()
    {
        // Primary Key
        HasKey(t => t.AreaId);

        // Properties
        Property(t => t.AreaName)
            .IsRequired()
            .HasMaxLength(256);

        // Table & Column Mappings 
        ToTable("AssetHealthAreas");
        Property(t => t.AreaId).HasColumnName("AreaId");
        Property(t => t.ParentId).HasColumnName("ParentId");
        Property(t => t.AreaName).HasColumnName("AreaName");
        Property(t => t.IsSubArea).HasColumnName("IsSubArea");

        // This is the discriminator column
        Map(m => m.Requires("IsSubArea").HasValue(true));

        HasRequired(a => a.Parent).WithMany(s => s.SubAreas).HasForeignKey(k => k.ParentId);
    }
}
modelBuilder.Entity<Area>()
    .Map<BuildingArea>(m => m.Requires("IsSubArea").HasValue(false))
    .Map<SubArea>(m => m.Requires("IsSubArea").HasValue(true));