9

mam następujący scenariuszjak uzyskać tabelę na klasę betonu, gdy klasa podstawowa jest abstrakcyjna w płynnym nhibernate?

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

dla mapowania Użyłem następujący fragment kodu: -

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(); 

Domyślnie płynną zignoruje abstrakcyjną klasę bazową, która jest klasy bazowej. Ale jak w klasie ProcessStep jest ContentElements własności, która zwraca IList, otrzymuję wyjątek: - NHibernate.MappingException: Stowarzyszenie referencje unmapped klas: klasy bazowej

Gdybym obejmują klasę bazową używając IncludeBase (typeof (BaseClass)) działa poprawnie, ale tworzy tabelę dla klas BaseClass i Derived, a rekordy są powiązane relacją FK-PK (tabela na podklasę). Co chcę osiągnąć, to tabela na klasę betonu. to jest każda klasa pochodna będzie miała swoją własną tabelę, gdzie będą wszystkie właściwości pochodnych klas + właściwości w klasie bazowej. Każdy pomysł, jak to osiągnąć?

Odpowiedz

9

Ponieważ nie widziałem twojego mapowania, pozwól mi podać moje. Można to osiągnąć poprzez działanie jak ten

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

używam Automap tak więc nie mam przepisu do mapowania klas osobno. – Niraj

+0

można mieszać automapie z niestandardowymi mapowaniami, dzięki czemu można udostępniać mapowanie tylko dla określonych klas, pozostałe klasy można odwzorować za pomocą automatyzacji. Coś takiego: Fluently.Configure (konfiguracja) .Mappings (cfg => {cfg.AutoMappings.Add (....); cfg..FluentMappings.AddFromAssembly (Twój niestandardowy zestaw mapowania);}) – Rajeesh

0

To spowodowało, że ból głowy w celu wdrożenia strategii „Tablica w klasie betonu” dziedziczenia z abstrakcyjnej klasy bazowej z NHibernate automapping. Ale myślę, że w końcu znalazłem rozwiązanie i chcę się z tobą podzielić. Myślę też, że nie jest dodawany do dokumentacji do automatyzacji, ponieważ może być uważany za "słaby" projekt bazy danych.

Pierwszy oto niektóre zasoby znalazłem na ten temat:

te zasoby w zasadzie opisać, jak trzeba to zrobić:

  1. Jak już wspomniano, płynny nhibernate ignoruje abstrakcyjne klasy bazowe. Musisz więc dodać je jawnie.
// abstractBaseTypes is just a simple enumeration of base types 
// model is the AutoPersistenceModel 
abstractBaseTypes.ForEach(m => model = model.IncludeBase(m)); 
  1. a) Jeśli znasz abstrakcyjne typy bazowe w czasie kompilacji można użyć
//sets the union subclass strategy for the known base model 
model.Override<SuperType>(m => m.UseUnionSubclassForInheritanceMapping())) 
  1. b) Jeśli nie znamy konkretnych typów można utworzyć nadpisanie mapowania dla każdego rodzaju podstawy:
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)); 
Powiązane problemy