1

這是我的場景(閱讀Fluent的第一個項目和自動映射頁面後)。我有幾乎相同的設置,除了我的一些約定不同於默認的表名和外鍵列名。我爲有問題的多對多關係提供了手動覆蓋;一面是反面,另一面不是。出於某種原因,這仍然不會級聯添加。我可以單獨手動添加圖像。我也可以成功地讀取整個架構的層次結構。當使用Fluent Nhibernate AutoMap時,我的多對多(全部級聯)沒有插入/更新兒童

我試過忽略手動manyToMany映射覆蓋;但我最終選擇了一個時髦的表名ImageToPhotoSession,失敗了。

任何想法?

我要提到我使用: NHibernate的3 流利1.2(測試版)

配置:

private readonly static ISessionFactory factory = 
Fluently.Configure() 
    .Database(MySQLConfiguration.Standard.ShowSql().ConnectionString(o => o.FromConnectionStringWithKey("Default"))) 
.Mappings(m => 
    m.AutoMappings.Add(AutoMap.AssemblyOf<Data.Image>(new TestMappingConfig()) 
     .Override<Data.PhotoSession>(map => map 
      .HasManyToMany<Data.Image>(o => o.Images) 
      .Cascade.All() 
      .Table("photo_session_image")) 
     .Override<Data.Image>(map => map 
      .HasManyToMany(x => x.PhotoSessions) 
      .Cascade.All() 
      .Inverse() 
      .Table("photo_session_image")) 
     .Conventions.Add(
      Table.Is(x => Inflector.Net.Inflector.Underscore(x.EntityType.Name)), 
      DefaultLazy.Always(), 
      DefaultCascade.All(), 
      ForeignKey.EndsWith("Id") 
))) 
.BuildSessionFactory(); 

這裏是我的數據實體:

public class Image 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual int SizeOnDisk { get; set; } 
    public virtual string Hash { get; set; } 
    public virtual int Width { get; set; } 
    public virtual int Height { get; set; } 
    public virtual string Description { get; set; } 
    public virtual string Caption { get; set; } 
    public virtual DateTime CreatedUtc { get; set; } 
    public virtual DateTime ModifiedUtc { get; set; } 
    public virtual DateTime ProcessedUtc { get; set; } 
    public virtual string ContentType { get; set; } 

    public virtual Site Site { get; set; } 
    public virtual IList<PhotoSession> PhotoSessions { get; private set; } 

    public Image() 
    { 
     this.PhotoSessions = new List<PhotoSession>(); 
    } 
} 

public class PhotoSession 
{ 
    public virtual int Id { get; private set; } 
    public virtual string Description { get; set; } 
    public virtual DateTime CreatedUtc { get; set; } 
    public virtual DateTime ModifiedUtc { get; set; } 
    public virtual DateTime? EventDate { get; set; } 

    public virtual IList<Image> Images { get; private set; } 
    public virtual Site Site { get; set; } 

    public PhotoSession() 
    { 
     Images = new List<Image>(); 
    } 

    public virtual void AddImage(Image data) 
    { 
     data.PhotoSessions.Add(this); 
     this.Images.Add(data); 
    } 
} 

這裏有一個片段我正在嘗試使用的代碼。

var repo = new Repository(); 
var site = repo.All<Data.Site>().Where(o => o.Id == 2).FirstOrDefault(); 
var img = new Data.Image() 
{ 
    Name = "test", 
    Caption = "test", 
    ContentType = "image/jpeg", 
    CreatedUtc = DateTime.UtcNow, 
    Description = "test", 
    Hash = "test", 
    Height = 23, 
    ModifiedUtc = DateTime.UtcNow, 
    SizeOnDisk = 23, 
    Width = 23 
}; 

site.AddImage(img); 

//one to many, actually calls session.SaveOrUpdate(object) - fails to insert img 
repo.Update(site); 

//gets a sample session 
var session = repo.All<Data.PhotoSession>().Where(o => o.Id == 25).FirstOrDefault(); 

session.AddImage(img); 

//many to many, actually calls session.SaveOrUpdate(object) - also fails to insert img and m2m row. 
repo.Update(session); 

最後,這裏是由Nhib編寫的Sql日誌。

NHibernate: select site0_.Id as Id3_, site0_.OwnerId as OwnerId3_, site0_.Layout 
as Layout3_, site0_.Alias as Alias3_, site0_.CreatedUtc as CreatedUtc3_, site0_ 
.Domains as Domains3_, site0_.DefaultPageId as DefaultP7_3_, site0_.ResourceKey 
as Resource8_3_ from site site0_ where site0_.Id=?p0 limit ?p1;?p0 = 2 [Type: In 
t32 (0)], ?p1 = 1 [Type: Int32 (0)] 

NHibernate: SELECT images0_.SiteId as SiteId1_, images0_.Id as Id1_, images0_.Id 
as Id0_0_, images0_.Name as Name0_0_, images0_.SizeOnDisk as SizeOnDisk0_0_, im 
ages0_.Hash as Hash0_0_, images0_.Width as Width0_0_, images0_.Height as Height0 
_0_, images0_.Description as Descript7_0_0_, images0_.Caption as Caption0_0_, im 
ages0_.CreatedUtc as CreatedUtc0_0_, images0_.ModifiedUtc as Modifie10_0_0_, ima 
ges0_.ProcessedUtc as Process11_0_0_, images0_.ContentType as Content12_0_0_, im 
ages0_.SiteId as SiteId0_0_ FROM image images0_ WHERE images0_.SiteId=?p0;?p0 = 
2 [Type: Int32 (0)] 

NHibernate: select photosessi0_.Id as Id2_, photosessi0_.AccessCode as AccessCod 
e2_, photosessi0_.Description as Descript3_2_, photosessi0_.CreatedUtc as Create 
dUtc2_, photosessi0_.ModifiedUtc as Modified5_2_, photosessi0_.EventDate as Even 
tDate2_, photosessi0_.SiteId as SiteId2_ from photo_session photosessi0_ where p 
hotosessi0_.Id=?p0 limit ?p1;?p0 = 25 [Type: Int32 (0)], ?p1 = 1 [Type: Int32 (0 
)] 

NHibernate: SELECT images0_.PhotoSessionId as PhotoSes2_1_, images0_.ImageId as 
ImageId1_, image1_.Id as Id0_0_, image1_.Name as Name0_0_, image1_.SizeOnDisk as 
SizeOnDisk0_0_, image1_.Hash as Hash0_0_, image1_.Width as Width0_0_, image1_.H 
eight as Height0_0_, image1_.Description as Descript7_0_0_, image1_.Caption as C 
aption0_0_, image1_.CreatedUtc as CreatedUtc0_0_, image1_.ModifiedUtc as Modifie 
10_0_0_, image1_.ProcessedUtc as Process11_0_0_, image1_.ContentType as Content1 
2_0_0_, image1_.SiteId as SiteId0_0_ FROM photo_session_image images0_ left oute 
r join image image1_ on images0_.ImageId=image1_.Id WHERE images0_.PhotoSessionI 
d=?p0;?p0 = 25 [Type: Int32 (0)] 
+0

我進一步測試,發現級聯作品爲一對多的關係,如果你要插入一個新的父(新的父,新的子)。但是,如果您有一個現有父級,並且您已經爲其添加了新的子級實例,則保存父級將不會將插入級聯級聯到新子級。 (如果這是有道理的)。這裏的多對多表「photo_session_image」仍未插入。 – Nathan 2011-03-14 19:21:12

回答

1

事實證明,我沒有將我的操作包裝在會話事務中。展望就在上流利NHibernates網站的樣本:

using (var session = sessionFactory.OpenSession()) 
{ 
    using (var transaction = session.BeginTransaction()) 
    { 
    //... do stuff 
    } 
} 

在這種情況下,國際奧委會一點,Repository類保持了內部以ISessionITransaction參考。在建立會議後,我建立了一個新的交易。然後,我做了RepositoryIDisposable,並在處置後,我承諾完成交易並關閉會話。我不應該參考Repository以外的任何Nhib內容。

所以在最後,我的代碼如下所示:

using (var repo = new Repository()) 
{ 
    ///do the same stuff in my third code sample from the question... 
} 
相關問題