2016-12-28 49 views
0

有人有任何想法使用NHibernate映射只创建多列上的引用吗?该映射只允许一列。定义NHibernate映射由多个列组成的主键上的代码

Bag(p => p.Childs, 
    map => 
    { 
     map.Key(k => 
      { 
       k.Column("KeyPart1"); 
      }); 
     map.Key(k => 
      { 
       k.Column("KeyPart2"); 
      }); 
    } 
    , ce => ce.OneToMany()); 

这导致在映射(剥离XML标签):

<bag name="Childs"> 
    <key column="KeyPart1" /> 
    <one-to-many class="Child" /> 
</bag> 

这导致错误: 结果消息:NHibernate.FKUnmatchingColumnsException:外键(FK1C5AAEC658BD05ED:儿童[KeyPart2]) )必须具有相同的数量引用的主键(父[KeyPart1,KeyPart2])

子映射是列:

ManyToOne(p => p.Parent, 
    map => map.Columns(
     col1 => 
     { 
      col1.Name("KeyPart1"); 
     }, 
     col2 => 
     { 
      col2.Name("KeyPart2"); 
     } 
     )); 

但我想我需要这种映射,与两个关键部分:

<bag name="Childs"> 
    <key column="KeyPart1" /> 
    <key column="KeyPart2" /> 
    <one-to-many class="Child" /> 
</bag> 

这是类的完整结构:

public class ParentIdentifier 
{ 
    public virtual string KeyPart1 { get; set; } 
    public virtual string KeyPart2 { get; set; } 

    public override bool Equals(object obj) 
    { 
     if (obj == null) 
      return false; 
     var t = obj as ParentIdentifier; 
     if (t == null) 
      return false; 
     if (KeyPart1 == t.KeyPart1 && KeyPart2 == t.KeyPart2) 
      return true; 
     return false; 
    } 

    public override int GetHashCode() 
    { 
     return (KeyPart1 + "|" + KeyPart2).GetHashCode(); 
    } 

    public override string ToString() 
    { 
     return string.Format("KeyPart1 = {0}; KeyPart2 = {1}", KeyPart1, KeyPart2); 
    } 
} 


[Serializable] 
public class Parent 
{ 
    #region Primary key 

    public virtual ParentIdentifier Id { get; set; } 

    #endregion Primary key 

    public Parent() 
    { 
     Childs = new List<Child>(); 
    } 

    public virtual IList<Child> Childs { get; set; } 
} 

public class ParentMap : ClassMapping<Parent> 
{ 
    public ParentMap() 
    { 
     Table("Parent"); 

     ComponentAsId(
      x => x.Id, 
      caim => 
      { 
       caim.Property(x => x.KeyPart1, pm => 
        { 
         pm.Column("KeyPart1"); 
         pm.Length(20); 
        }); 
       caim.Property(x => x.KeyPart2, pm => 
        { 
         pm.Column("KeyPart2"); 
         pm.Length(64); 
        }); 
      }); 

     Bag(p => p.Childs, 
      map => 
      { 
       map.Key(k => 
        { 
         k.Column("KeyPart1"); 
        }); 
       map.Key(k => 
        { 
         k.Column("KeyPart2"); 
        }); 
      } 
      , ce => ce.OneToMany()); 
    } 
} 

[Serializable] 
public class Child 
{ 
    #region Primary key 

    public virtual int ChildId { get; set; } 

    #endregion Primary key 

    public virtual Parent Parent { get; set; } 
} 


public class ChildMap : ClassMapping<Child> 
{ 
    public ChildMap() 
    { 
     Table("Child"); 

     Id(p => p.ChildId, 
      map => 
       { 
        map.Generator(Generators.Assigned); 
        map.Column("ChildId"); 
       }); 

     ManyToOne(p => p.Parent, 
      map => map.Columns(
       col1 => 
       { 
        col1.Name("KeyPart1"); 
       }, 
       col2 => 
       { 
        col2.Name("KeyPart2"); 
       } 
       )); 
    } 
} 

回答

0

因为您呼叫map.Key(.. 。)两次,第二个覆盖第一个!你应该改为:

map.Key(k => 
     { 
      k.Columns(
       c1 => c1.Name("c1"), 
       c2 => c2.Name("c2") /*as many as you want*/ 
      ); 
     });