解决方案 »

  1.   

    补充:
    想要代码实现的结构为:
    class A
    {
        public int AutoId{get;set;}
        public string K1{get;set;}
        public string K2{get;set;}
        public string K3{get;set;}
        public string P1{get;set;}
        public string P2{get;set;}
        public IList<B> BList{get;set;}
    }class B
    {
        public int AutoId{get;set;}
        public string K1{get;set;}
        public string K2{get;set;}
        public string K3{get;set;}
        public string P3{get;set;}
        public string P4{get;set;}
        public A A{get;set;}
    }
      

  2.   

    话说,你这样设计,完全没有意义
    既然表B里的内容和表A的一样,那它就完全没必要出现在表B里
    你应该这样设计:
    表A
    AutoId,K1,K2,K3,P1,P2
    表B
    AutoId,AID,P3,P4
    用AID于表A的AutoId关联就可以了
      

  3.   


    public class A
    {
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int AutoId { get; set; }    [Key, Column(Order = 0)]
        public string K1 { get; set; }
        [Key, Column(Order = 1)]
        public string K2 { get; set; }
        [Key, Column(Order = 2)]
        public string K3 { get; set; }    public string P1 { get; set; }
        public string P2 { get; set; }    public virtual ICollection<B> BList { get; set; }
    }public class B
    {
        [Key]
        public int AutoId { get; set; }    [ForeignKey("A"), Column(Order = 0)]
        public string K1 { get; set; }
        [ForeignKey("A"), Column(Order = 1)]
        public string K2 { get; set; }
        [ForeignKey("A"), Column(Order = 2)]
        public string K3 { get; set; }    public string P3 { get; set; }
        public string P4 { get; set; }    public virtual A A { get; set; }
    }
      

  4.   

    感谢这位大侠!下面三点疑惑:
    1. 这个Order就是Key的标识么?
    2. 这个是CodeFirst的模式吧,如果我使用DBFirst,然后在用.edmx的视图编辑应该如何操作呢?
    3. 如果A表中K1,K2,K3不唯一.........这样做会抛错么?
      

  5.   

    1. Order是用来表示组合键的顺序,Key是用来表示键的
    2. 我试验了下,DbFirst的约束更大,要看你数据库的结构了,如果原来A表的主键是AutoId,那DbFirst做不到直接映射,它的关联必须是外键和主键关联的,就没法把B上的(K1,K2,K3)关联到A的(K1,K2,K3)了。如果A上的主键本来就是(K1,K2,K3)那就可以映射。
    3. (K1,K2,K3)组合键必须唯一,否则从B关联A就不是一种情况,这样肯定不能直接关联了。我估计你的情况是数据库里面A表主键是AutoId,K1,K2,K3也并没有做唯一键约束,这样是没法在数据库和EF层面关联的。如果要关联就要保证A表的(K1,K2,K3)组合唯一,在数据库A表建立(K1,K2,K3)的唯一键约束,B表就可以建立外键关联了。只有这样EF才能使用这个关联来做entity上的属性关联。如果你的数据库可以做上面说的改动,那DbFirst的方式也不支持这样的关联,需要用CodeFirst的方式来自己建立新的DbContext和实体来做查询。CodeFirst也不是非要从code创建、修改数据库结构,我给的例子其实也是我手动建了数据库,然后再用CodeFirst做的(因为CodeFirst的约束比较弱,能支持不关联主键的外键)。如果不能做上面的改动,那就没办法实现直接关联了。
      

  6.   

    非常感谢“github_22161131”大神的热心答复!
    我觉得你说的很有道理,不过数据库我是动不了的,那么如果我把A-B的关系变为多对多,使用这种关联可以么?(可以使用CodeFirst的方式)即:class A
    {
        public int AutoId{get;set;}
        public string K1{get;set;}
        public string K2{get;set;}
        public string K3{get;set;}
        public string P1{get;set;}
        public string P2{get;set;}
        public ICollection<B> BList{get;set;}
    }class B
    {
        public int AutoId{get;set;}
        public string K1{get;set;}
        public string K2{get;set;}
        public string K3{get;set;}
        public string P3{get;set;}
        public string P4{get;set;}
        public ICollection<A> AList{get;set;}
    }
      

  7.   

    那还是不行的,多对多实际是通过一张中间表实现的,它有A的外键,也有B的外键,需要A上的(K1,K2,K3),和B上的(K1,K2,K3)有唯一约束才能建立外键。如果不能保证(K1,K2,K3)的唯一性,就无法建立外键,就只能想别的办法了。
      

  8.   

    好的 感谢github_22161131的回答,受益良多,顺便问一句;EF 6的CodeFirst模式支持继承么?即:[NoMapped]
    public class EntityBase
    {
        [Key]
        public int AutoId{get;set;}
        public string K1{get;set;}
        public string K2{get;set;}
        public string K3{get;set;}
    }
    public class A : EntityBase
    {
        pubilc string P1{get;set;}
        pubilc string P2{get;set;}
    }
    public class B: EntityBase
    {
        pubilc string P3{get;set;}
        pubilc string P4{get;set;}
    }要实现类似这样的结构设计 应该如何实现呢?
      

  9.   

    支持继承,EF的继承关系映射到数据库有三种方式,我简单说
    1. Table per Hierarchy (TPH)
    就是基类和子类都映射到一张表,通过一个额外的字段区别是那个类。  2. Table per Type (TPT)
    就是每个类一张表,子类表和基类表是主键关联1:1的关系。3. Table per Concrete Type (TPC)
    就是基类不映射,而是其属性都在子类展开,每个子类一张表。像你给的结构应该是用TPC,和之前一样映射到A,B两张表。这个最简单,写成public abstract class EntityBase
    {
        [Key]
        public int AutoId{get;set;}
        public string K1{get;set;}
        public string K2{get;set;}
        public string K3{get;set;}
    }
    public class A : EntityBase
    {
        pubilc string P1{get;set;}
        pubilc string P2{get;set;}
    }
    public class B: EntityBase
    {
        pubilc string P3{get;set;}
        pubilc string P4{get;set;}
    }这样基类是abstract的,EF就自动TPC了。具体的说明我觉得写的比较详细的是http://weblogs.asp.net/manavi/associations-in-ef-4-1-code-first-part-1-introduction-and-basic-concepts