2013-07-13 29 views
6

Câu hỏi của tôi là, có một bản đồ có thể Fluent NHibernate cho các đối tượng Parent và Child không yêu cầu đối tượng Child có thuộc tính Parent object không? Tôi đã không tìm ra cách ánh xạ tham chiếu trở lại với Phụ Huynh. Khi tôi gọi Create với ánh xạ như là, tôi nhận được một ngoại lệ vì đối tượng Child không có khóa ngoài yêu cầu (bắt buộc trong kho dữ liệu) trở lại Parent.Bản đồ chìa khóa nước ngoài trong Fluent NHibernate mà không có thuộc tính đối tượng

Tôi có hai lớp POCO:

public class Parent 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual IList<Child> Childs { get; set; } 
} 

public class Child 
{ 
    public virtual int Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual int ParentId { get; set; } 
} 

Và một số ánh xạ:

public class ParentMap : ClassMap<Parent> 
{ 
    public ParentMap() 
    { 
     this.Table("Parents"); 
     this.Id(x => x.Id); 
     this.Map(x => x.Name); 
     this.HasMany(x => x.Childs).KeyColumn("ChildId").Cascade.AllDeleteOrphan(); 
    } 
} 

public class ChildMap : ClassMap<Child> 
{ 
    public ChildMap() 
    { 
     this.Table("Childs"); 
     this.Id(x => x.Id); 
     this.Map(x => x.Name); 
     // Needs some sort of mapping back to the Parent for "Child.ParentId" 
    } 
} 

Và Tạo phương pháp:

public Parent Create(Parent t) 
{ 
    using (this.session.BeginTransaction()) 
    { 
     this.session.Save(t); 
     this.session.Transaction.Commit(); 
    } 
    return t; 
} 

Tôi muốn để có thể tạo ra một đối tượng phụ huynh mà có một danh sách các đối tượng con, nhưng không có các đối tượng con có tham chiếu trở lại cha mẹ của họ (khác với ID cha mẹ). Tôi muốn làm điều này để tránh tham chiếu vòng tròn từ Parent đến một danh sách Childs quay lại đối tượng Parent, vì nó gây ra các vấn đề với serialization JSON.

+0

Đang ánh xạ thuộc tính cha mẹ (trong 'Con') sang trường riêng tư một tùy chọn? –

+0

Đó là những gì tôi đang làm, mặc dù tôi đang cố gắng tránh nó vì tôi không thể chạy truy vấn trên thuộc tính 'ParentId'. Có vẻ như tôi sẽ có thể ánh xạ một thuộc tính với một ràng buộc khóa ngoài tới một cột mà không cần một đối tượng ... –

+0

Trong trường hợp của câu hỏi ban đầu, câu trả lời của Felipe là chính xác. Không tuần tự hóa các thực thể trực tiếp, chuyển đổi chúng thành một DTO hoặc ViewModel đầu tiên, nhận được cấu trúc chính xác mà bạn muốn đầu tiên. –

Trả lời

3

Bạn có thể lập bản đồ các thực thể mà không có vấn đề, hãy thử này:

public class ParentMap : ClassMap<Parent> 
{ 
    public ParentMap() 
    { 
     this.Table("Parents"); 
     this.Id(x => x.Id); 
     this.Map(x => x.Name); 
     this.HasMany(x => x.Childs).KeyColumn("ChildId").Cascade.AllDeleteOrphan(); 
    } 
} 

public class ChildMap : ClassMap<Child> 
{ 
    public ChildMap() 
    { 
     this.Table("Childs"); 
     this.Id(x => x.Id); 
     this.Map(x => x.Name); 
     this.Map(x => x.ParentId); 
     // if you have a reference of Parent object, you could map as a reference, for sample: 
     this.References(x => x.Parent).Column("ParentId"); 
    } 
} 

Khi bạn nhận được các đơn vị từ ISession, không serialize nó vào một số định dạng bởi vì chúng có thể được proxy của nhibernate thay vì đối tượng thực thể. Hãy thử tạo DTO (Data Transfer Object) classes và chuyển đổi các thực thể này thành đối tượng DTO và tuần tự hóa nó. Bạn sẽ tránh tham chiếu vòng tròn. Đối với mẫu:

public class ParentDTO 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public int ParentId { get; set; } 

    /* here you just have the primitive types or other DTOs, 
     do not reference any Entity type*/ 
} 

Và khi bạn cần phải đọc các giá trị để chia sẻ giá trị serialized:

var dto = ISession.Query<Parent>() 
        .Select(x => 
         new ParentDTO() { 
          Id = x.Id, 
          Name = x.Name, 
          ParentId = x.ParentId) 
        .ToList(); 

Nhận kết quả này từ Data Access Layer và cố gắng serialize, cho mẫu:

var result = Serialize(dto); 
+1

Một phần quan trọng đối với tôi rằng câu trả lời của bạn không giải quyết là thuộc tính 'ParentId' phải có một ràng buộc khóa ngoài trên thuộc tính' Id' của đối tượng 'Parent'. Bạn chỉ cần 'Map'nhập nó, vì vậy nó không có ràng buộc gì cả. –

+0

Tôi đồng ý với bạn @PatrickQuirk, nhưng trong mô hình OP được cung cấp không có tham chiếu, chỉ là một 'Id'. –