9

tôi có các tình huống saulàm thế nào để đạt được bảng cho mỗi lớp bê tông khi lớp cơ sở là trừu tượng trong nhibernate thông thạo?

public abstract class BaseClass 
{ 
    public virtual int Id {get; set}; 
    public virtual string Name {get; set;} 
} 

public class FirstSubClass : BaseClass 
{ 
    //properties and behaviour here 
} 

public class SecondSubClass : BaseClass 
{ 
    //properties of SecondSubclass Here 
} 

public class ProcessStep 
{ 
    public virtual IList<BaseClass> ContentElements {get; set;} 
} 

để lập bản đồ tôi đã sử dụng đoạn mã sau: -

this._sessionFactory = 
          Fluently.Configure().Database(SQLiteConfiguration.Standard 
          .ConnectionString(@"Data Source=SqliteTestSqlDataAccess.s3db; Version=3; New=True; Pooling=True; Max Pool Size=1;")) 
          .Mappings(m => m.AutoMappings.Add(AutoMap.Assembly(assemblyWithDomainClasses).Conventions.Add(DefaultCascade.All()))) 
          .ExposeConfiguration(BuildSchema) 
          .BuildSessionFactory(); 

Theo mặc định thông thạo sẽ bỏ qua các lớp cơ sở trừu tượng đó là BaseClass. Nhưng khi trong lớp ProcessStep có ContentElements tài sản mà trả IList, tôi đang nhận một ngoại lệ: - NHibernate.MappingException: Hiệp hội tài liệu tham khảo unmapped lớp: BaseClass

Nếu tôi bao gồm các lớp cơ sở sử dụng IncludeBase (typeof (BaseClass)) sau đó nó hoạt động tốt nhưng nó tạo ra một bảng cho các lớp BaseClass và Derived và các bản ghi được liên kết với mối quan hệ FK-PK (bảng trên mỗi lớp con). Điều tôi muốn đạt được là bảng cho mỗi lớp bê tông. đó là mỗi lớp dẫn xuất sẽ có bảng riêng của nó, nơi sẽ có tất cả các thuộc tính của các thuộc tính lớp dẫn xuất + trong lớp cơ sở. Bất kỳ ý tưởng nào để đạt được điều đó?

Trả lời

9

Vì tôi chưa thấy bản đồ của bạn, hãy để tôi cung cấp cho tôi. Bạn có thể đạt được điều này bằng cách thực hiện như thế này

public class BaseClassMap:ClassMap<BaseClass> 
{ 
    public BaseClassMap() 
    { 
     /* 
     * Identity generator can't be native because subclass objects should be unique 
     * So use HiLo or Guid or other generators which will generate unique id on the child tables 
     */ 
     Id(x => x.Id).GeneratedBy.Guid(); 
     Map(x => x.Name); 
     UseUnionSubclassForInheritanceMapping(); // This is important - uses union-subclass mappings for the derived classes 
    } 
} 

public class FirstSubClassMap : SubclassMap<FirstSubClass> 
{ 
    public FirstSubClassMap() 
    { 
     Table("FirstSubClassTable"); 
     // Map properties for FirstSubClass 
    } 
} 

public class SecondSubClassMap : SubclassMap<SecondSubClass> 
{ 
    public SecondSubClassMap() 
    { 
     Table("SecondSubClassTable"); 
     // Map properties for SecondSubClass 
    } 
} 
+1

tôi đang sử dụng Tự động hóa như vậy, tôi không có điều khoản để ánh xạ các lớp một cách riêng biệt. – Niraj

+0

bạn có thể trộn tự động với ánh xạ tùy chỉnh, để bạn có thể cung cấp ánh xạ chỉ cho các lớp cụ thể, phần còn lại của các lớp có thể được ánh xạ bằng cách sử dụng tự động hóa. Một cái gì đó như thế này Fluently.Configure (cấu hình) .Mappings (cfg => {cfg.AutoMappings.Add (....); cfg..FluentMappings.AddFromAssembly (Bản đồ tùy chỉnh của bạn);}) – Rajeesh

0

Nó khiến tôi đau đầu thực hiện chiến lược thừa kế "Bảng cho mỗi lớp bê tông" với lớp cơ sở trừu tượng với tự động nhibernate. Nhưng tôi nghĩ, cuối cùng tôi đã tìm ra một giải pháp và muốn chia sẻ nó với bạn. Tôi cũng nghĩ rằng, nó không được thêm vào các tài liệu tự động hóa, bởi vì nó có thể được coi là một thiết kế cơ sở dữ liệu "yếu".

Đầu tiên đây là một số nguồn tôi thấy về chủ đề này: thực hiện

Những nguồn lực về cơ bản mô tả cách bạn cần phải làm điều đó:

  1. Như bạn đã đề cập thông thạo nhibernate bỏ qua các lớp cơ sở trừu tượng. Vì vậy, bạn cần phải thêm chúng một cách rõ ràng.
// abstractBaseTypes is just a simple enumeration of base types 
// model is the AutoPersistenceModel 
abstractBaseTypes.ForEach(m => model = model.IncludeBase(m)); 
  1. a) Nếu bạn biết các loại cơ sở trừu tượng ở thời gian biên dịch, bạn có thể sử dụng
//sets the union subclass strategy for the known base model 
model.Override<SuperType>(m => m.UseUnionSubclassForInheritanceMapping())) 
  1. b) Nếu bạn không biết các loại bê tông bạn có thể tạo một ghi đè lên bản đồ cho từng loại cơ sở:
public class AbstractRightEntryMappingOverride : IAutoMappingOverride<AbstractRightEntry> 
{ 
    public void Override(AutoMapping<AbstractRightEntry> mapping) 
    { 
     mapping.UseUnionSubclassForInheritanceMapping(); 
    } 
} 

// You need to tell nhibernate where to find the overriden mappings. 
// You simply can add the assemblies again. 
modelAssemblies.ForEach(a => model = model.UseOverridesFromAssembly(a)); 
Các vấn đề liên quan