Fluent Nhibernate如何在级联保存期间为非空列设置值

时间:2013-12-12 13:19:01

标签: c# nhibernate fluent-nhibernate nhibernate-mapping fluent-nhibernate-mapping

我有以下关系表:

public class Physicians
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual List<Specialty> Specialties{ get; set; }
    public virtual User CreatedBy { get; set; }
}

public class Specialties
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }    
    public virtual User CreatedBy { get; set; }
}


public class PhysicianSpecialtyBridge
{
   public virtual Physicians Physician{get; set;}
   public virtual Specialties Specialty { get; set; }
   public virtual User CreatedBy { get; set; }
}

在我指定为

的映射中
 HasManyToMany(physician => physician.Specialties).Table("PhysicianSpecialty")
.ParentKeyColumn("Physician").ChildKeyColumn("Specialty").Cascade.All;

当我尝试将医生与专业列表关联并进行保存时,我遇到的问题是,在尝试插入桥接表时失败,因为PhysicianSpecialtyBridge中的createdby键不为空。当我使列可以为空时,一切正常。解决这个问题的任何方法?出于某种原因,我还需要在我的桥接表中维护“CreatedBy”。

1 个答案:

答案 0 :(得分:0)

这里的问题是,当您使用many-to-many映射时,C#实体代表不同的关系。情景中使用Many-to-many,1)我们有一个配对表,但1)没有C#实体用于表示。

A)我建议,如果你想保持配对对象为C#实体来改变你的模型。它应该是这样的:

1)配对表应该有自己的代理键

public class PhysicianSpecialtyBridge
{
   // the pairing object should have the ID
   public virtual int Id { get; set; }
   public virtual Physician  Physician { get; set; }
   public virtual Speciality Speciality{ get; set; }
   ...

2)另一个对象应该列出配对对象(注意我对实体名称使用了单数)

public class Physician
{
    ...
    public virtual List<PhysicianSpecialtyBridge> Specialties{ get; set; }


public class Specialty
{
    ...
    public virtual List<PhysicianSpecialtyBridge> Physicians{ get; set; }

然后配对对象的映射就像

References( x => x.Physician);
References( x => x.Specialty);

现在,医生与one-to-many成对配对

HasMany(x => x.Specialties)
  .Inverse()
  .Cascade.All(); 

专业类似

HasMany(x => x.Physicians)
  .Inverse()
  .Cascade.All(); 

B)如果你真的想要多对多,那么你必须删除Pairing对象。 C#Entites将是这样的:

public class Physician
{
    ...
    public virtual List<Specialty> Specialties{ get; set; }


public class Specialty
{
    ...
    public virtual List<Physician> Physicians{ get; set; }

和映射

医生

HasManyToMany(x => x.Specialties)
  .Table("PhysicianSpecialty")
  .ParentKeyColumn("Specialty")
  .ChildKeyColumn("Physician")
  .Inverse()
  //.Cascade.All() - NO Cascade, pairing table will be managed by default
  ; 

专业

HasManyToMany(x => x.Physicians)
  .Table("PhysicianSpecialty")
  .ParentKeyColumn("Physician")
  .ChildKeyColumn("Specialty")
  // .Inverse() - NOT INVERSE, only one can be
  // .Cascade.All() - NO Cascade, that will remove the Speciality
  ; 

A)方法更好并且建议。其中一个优点是,您的配对对象可以具有更多属性(例如CreatedBy或Order ... IsActive)......并且您还可以使用子查询搜索具有某种特殊类型的Physcians

请检查Chapter 24. Best Practices。提取

  

不要使用异国情调的关联映射。

     

真正的多对多关联的良好用例很少见。大多数   您需要存储在“链接表”中的其他信息的时间。   在这种情况下,使用两个一对多关联要好得多   中间链接类。事实上,我们认为大多数协会   是一对多和多对一,你在使用任何时都要小心   其他协会风格,并问自己是否真的有必要。

另外,您可以查看Nhibernate: How to represent Many-To-Many relationships with One-to-Many relationships?以获取有关多对多替代方案的更多详细信息。关于子查询的优点的一些阅读可以在https://stackoverflow.com/a/14080092/1679310

找到