Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.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#_Entity Framework_Ef Code First - Fatal编程技术网

C# 使用继承时设置外键关联的正确方法

C# 使用继承时设置外键关联的正确方法,c#,entity-framework,ef-code-first,C#,Entity Framework,Ef Code First,我的数据库中有两个表:Masters和Details 这些表与外键约束一对多相关,其中的Masters是主键表,Details是外键表 我想在我的模型中对Masters表中的实体使用继承: abstract class Master { public int Id { get; set; } } class Master_1 : Master { // other properties } class Master_2: Master { // other prope

我的数据库中有两个表:
Masters
Details

这些表与外键约束一对多相关,其中的
Masters
是主键表,
Details
是外键表

我想在我的模型中对
Masters
表中的实体使用继承:

abstract class Master
{
    public int Id { get; set; }
}

class Master_1 : Master
{
    // other properties
}

class Master_2: Master
{
    // other properties
}
abstract class Detail
{
    public int Id { get; set; }
}

class Detail_1 : Detail
{
    // other properties
}

class Detail_2: Detail
{
    // other properties
}

class Detail_3: Detail
{
    // other properties
}
对于
明细表中的实体:

abstract class Master
{
    public int Id { get; set; }
}

class Master_1 : Master
{
    // other properties
}

class Master_2: Master
{
    // other properties
}
abstract class Detail
{
    public int Id { get; set; }
}

class Detail_1 : Detail
{
    // other properties
}

class Detail_2: Detail
{
    // other properties
}

class Detail_3: Detail
{
    // other properties
}
但是外键呢?
从概念上讲,
Master_1
应该只包含
Detail_1
细节,
Master_2
应该包含
Detail_2
或者
Detail_3
细节

如果我想从实体框架中抽象,我会为
Detail\u2
Detail\u3
添加中间基类:

   abstract class Detail_2_Or_3 : Detail {}
   class Detail_2 : Detail_2_Or_3 {}
   class Detail_3 : Detail_2_Or_3 {}
并使我的
Master
通用:

abstract class Master<TDetail>
    where TDetail : Detail
{
    public int Id { get; set; }
    public Collection<TDetail> Details { get; private set; }
}

class Master_1 : Master<Detail_1> {}
class Master_2 : Master<Detail_2_Or_3> {}
抽象类主控
where TDetail:详细信息
{
公共int Id{get;set;}
公共集合详细信息{get;private set;}
}
类Master_1:Master{}
类Master_2:Master{}
但如何使用实体框架实现这一点呢?当
Master
有一个
详细信息的集合时,我不喜欢这个解决方案,因为这不能提供编译时保证

我正在寻找在
Master
Detail
层次结构上没有附加层的方法。
有什么想法吗?

这只是一个想法,我还没有用EF完全尝试过,但是

为什么不按照您所说的那样进行设置,并在您的域对象上使用一组限制性的公共方法来提供编译时安全性呢

也就是说,Master是在EF中用一个细节集合设置的,但是您只能将Detail_1的实例添加到Master_1的实例中,等等。然后您可以有一个方法,该方法也可以返回适合于基类型的强类型集合

代码如下:

public abstract class Master<TDetail> where TDetail : Detail
{
    public int Id { get; set; }
    public List<Detail> Details { get; private set; }

    public abstract void AddDetail(TDetail detail);
    public abstract List<TDetail> GetDetails();
}

public class Master_1 : Master<Detail_1> 
{
    public override void AddDetail(Detail_1 detail) 
    {
        Details.Add(detail);
    }

    public override List<Detail_1> GetDetails()
    {
        return Details.Select(d => (Detail_1)d).ToList();
    }
}

public class Master_2 : Master<Detail_2_Or_3> 
{
    public override void AddDetail(Detail_2_Or_3 detail)
    {
        Details.Add(detail);
    }

    public override List<Detail_2_Or_3> GetDetails()
    {
        return Details.Select(d => (Detail_2_Or_3)d).ToList();
    }
}

public abstract class Detail
{
    public int Id { get; set; }

    //Foriegn Key
    public int MasterId { get; private set;}
}

public class Detail_1 : Detail { }

public abstract class Detail_2_Or_3 : Detail { }
public class Detail_2 : Detail_2_Or_3 { }
public class Detail_3 : Detail_2_Or_3 { }  
公共抽象类主节点,其中TDetail:Detail
{
公共int Id{get;set;}
公共列表详细信息{get;private set;}
公开摘要无效详细信息(详细信息);
公共摘要列表GetDetails();
}
公开课硕士1:硕士
{
公共覆盖无效添加详细信息(详细信息_1详细信息)
{
详细信息。添加(详细信息);
}
公共覆盖列表GetDetails()
{
返回详细信息。选择(d=>(Detail_1)d.ToList();
}
}
公开课硕士2:硕士
{
公共覆盖无效添加详细信息(详细信息\u 2\u或\u 3详细信息)
{
详细信息。添加(详细信息);
}
公共覆盖列表GetDetails()
{
返回详细信息。选择(d=>(Detail_2_或_3)d.ToList();
}
}
公共抽象类详细信息
{
公共int Id{get;set;}
//外键
public int MasterId{get;private set;}
}
公共类详细信息_1:详细信息{}
公共抽象类Detail_2_或_3:Detail{}
公共类Detail_2:Detail_2_或_3{}
公共类Detail_3:Detail_2_或_3{}

这是一本有趣的读物,希望能为您提供思考的食物@PaulZahra:我不认为,对TPC继承的描述会有所帮助。可能是我遗漏了什么?你看过TPT和TPH吗?问题不在于选择继承模型(在这种特殊情况下,选择TPT)。问题是如何配置关系,从而提供编译时安全性。对于抽象类,关联必须仅引用其子类之一的实例。