简体   繁体   English

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

[英]Fluent Nhibernate how to set values for not null columns during cascade save

I have tables with following relationship: 我有以下关系表:

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; }
}

In the mapping i have specified as 在映射中,我指定为

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

The issue i have when i try to associate the Physician with the list of specialties and do a save, it is failing while trying to insert into the bridge table because the createdby key in PhysicianSpecialtyBridge is not null. 当我尝试将Physician与专业列表相关联并进行保存时,我遇到的问题是,由于PhysicianSpecialtyBridge中的createdby键不为null,因此尝试插入到桥接表时失败。 When i make the column nullable, everything works fine. 当我使列为可空时,一切正常。 Any solution for this problem? 这个问题有解决方案吗? For some reason i need to maintain "CreatedBy" in my bridge table as well. 由于某种原因,我还需要在桥表中维护“ CreatedBy”。

The issue here is, that while you are using many-to-many mapping, the C# Entities represent different relation. 这里的问题是,当您使用many-to-many映射时,C#实体表示不同的关系。 Many-to-many is used in scenarios, when 1) we have a pairing table, but 1) there is no C# Entity for its represenation. 在方案中使用Many-to-many时,当1)我们有一个配对表,但1)没有用于表示的C#实体。

A) I would suggest, if you want to keep the pairing object as C# entity to change your model. A)我建议,如果要将配对对象保留为C#实体以更改模型。 It should be like this: 应该是这样的:

1) The pairing table should have its own surrogated key 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) the other object should list the pairing object (NOTE I used singular for entity names) 2)另一个对象应列出配对对象(注意,我在实体名称中使用单数形式)

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


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

Then the mapping of the Pairing object would be like 然后配对对象的映射就像

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

The Physicians is now in relation one-to-many to pairing object 现在,医师与配对对象one-to-many

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

The Specialties is similar 特色相似

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

B) If you really want many-to-many, then you have to remove the Pairing object. B)如果您确实想要多对多,则必须删除配对对象。 The C# Entites will be like this: C#实体将如下所示:

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


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

And the mapping 和映射

The Physicians 内科医生

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

The Specialties 特色菜

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
  ; 

The A) approach is better and suggested. A)方法更好,建议使用。 One of advantages is, that your pairing object could have more properties (eg CreatedBy or Order ... IsActive)... and you also gain the ability to search with subqueries for Physcians having some type of Specialities 优点之一是,您的配对对象可以具有更多属性(例如,CreatedBy或Order ... IsActive)...,并且您还可以通过子查询搜索具有某些特殊类型的医师

Please check Chapter 24. Best Practices . 请检查第24章 Extract 提取

Don't use exotic association mappings. 不要使用奇异的关联映射。

Good usecases for a real many-to-many associations are rare. 真正的多对多关联的好用例很少。 Most of the time you need additional information stored in the "link table". 大多数时候,您需要存储在“链接表”中的其他信息。 In this case, it is much better to use two one-to-many associations to an intermediate link class. 在这种情况下,最好将两个一对多关联用于中间链接类。 In fact, we think that most associations are one-to-many and many-to-one, you should be careful when using any other association style and ask yourself if it is really neccessary. 实际上,我们认为大多数关联是一对多和多对一的,在使用任何其他关联样式时应格外小心,并问自己是否真的必要。

Also you can check Nhibernate: How to represent Many-To-Many relationships with One-to-Many relationships? 您还可以检查Nhibernate:如何用一对多关系表示多对多关系? for more details about the alternative of the many-to-many. 有关多对多替代方案的更多详细信息。 Some reading about advantages of subqueries could be found here https://stackoverflow.com/a/14080092/1679310 有关子查询优点的一些信息可以在这里找到https://stackoverflow.com/a/14080092/1679310

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM