2009-03-23 13 views
31

Acabo de cambiar a Fluiber NHibernate y me he encontrado con un problema y no he encontrado ninguna información al respecto.Fluido NHibernate, trabajando con interfaces

Aquí es el caso:

public class Field : DomainObject, IField 
{ 
    public Field() 
    { 
    } 

    public virtual string Name { get; set; } 
    public virtual string ContactPerson { get; set; } 
    public virtual bool Private { get; set; } 
    public virtual IAddress Address { get; set; } 
} 

IAddress es una interfaz implementada por una clase llamada Dirección

public class Address : DomainObject, IAddress 
{ 
    public Address() 
    { 
    } 

    public virtual string City { get; set; } 
    public virtual string Country { get; set; } 
    public virtual string PostalCode { get; set; } 
    public virtual string StreetAddress { get; set; } 
} 

He aquí mis archivos de asignación para ambas clases

DIRECCIÓN

public class AddressMap : ClassMap<Address> 
{ 
    public AddressMap() 
    { 
     WithTable("Addresses"); 
     Id(x => x.Id, "Id").Access.AsCamelCaseField(Prefix.Underscore).GeneratedBy.Guid(); 
     Map(x => x.City, "City"); 
     Map(x => x.Country, "Country"); 
     Map(x => x.PostalCode, "PostalCode"); 
     Map(x => x.StreetAddress, "StreetAddress"); 
    } 
} 

CAMPO

public class FieldMap : ClassMap<Field> 
{ 
    public FieldMap() 
    { 
     WithTable("Fields"); 
     Id(x => x.Id, "Id").Access.AsCamelCaseField(Prefix.Underscore).GeneratedBy.Guid(); 
     Map(x => x.Name, "Name"); 
     Map(x => x.ContactPerson, "ContactPerson"); 
     Map(x => x.Private, "Private"); 
     References(x => x.Address, "AddressId").Cascade.Delete().Cascade.SaveUpdate(); 
    } 
} 

Así que cuando traté de retrive un objeto de campo de mi base de datos, me sale un error que indica que NHibernate IAddress no está asignada. ¿Hay alguna forma de especificar a NHibernate para usar la clase Address en la asignación?

Háganme saber si necesita más información.

Muchas gracias,

Charles

+0

¿Cómo está modelando la jerarquía de IAddress en la base de datos? ¿Tabla por jerarquía (una tabla que contiene todos los tipos de dirección) o tabla por clase concreta? Dijiste que cambiaste a Fluent, por lo que publicar un mapa XML de ejemplo podría ayudarte a determinar lo que intentas lograr. –

+0

De hecho, cambié de ADO.NET Entity Framework a Nhibernate con Fluidez NHibernate. En mi base de datos, hay una tabla que contiene todos los tipos de dirección. Por cierto, decidí eliminar esas interfaces, me di cuenta de que era inútil. Pero creo que la pregunta sigue siendo válida. Gracias, Charles –

Respuesta

35

Me parece que hay razones válidas para usar una interfaz en lugar de una clase concreta como una propiedad.

Por ejemplo, si su clase de campo estaba en un proyecto separado para la clase de dirección, y no tenía una dependencia en el proyecto de la clase de dirección del proyecto de la clase de campo.

Hay otras maneras de manejar esta situación, pero la manera más simple es a menudo intentar lo que está haciendo y explicity le dice a NHibernate la clase concreta que se debe usar para IAddress.

Ahora puede hacer esto en Fluido NHibernate, así:

References(x => x.Address, "AddressId") 
    .Class(typeof(Address); 

Lamentablemente no se puede hacer esto con hasMany o HasManyToMany. No estoy seguro de si esto sería posible debido a la falta de un buen soporte de covarianza en C#.

+26

** Actualización: ** Se puede usar 'Referencias

(x => x.Address) .Column ("AddressID");' Puede hacer lo mismo con 'hasMany' y 'HasManyToMany' agregando el parámetro de tipo genérico. – Jay

+0

+1 para actualizar, justo lo que estaba buscando, muchas gracias. – 4imble

+0

Muchas gracias, exactamente lo que estaba buscando también ... intenté hacer .CollectionType() encadenado en mi HasMany(), pero eso no pareció funcionar. – calebt

5

En el objeto de campo, que tienen un objeto de tipo IAddress. Esto podría implementarse mediante cualquier cantidad de implementaciones diferentes. Con lo que está preguntando, cada implementación tendría su propia asignación, que introduciría cualquier cantidad de dificultades (¿imposibilidades?) Que NHibernate podría manejar.

Un simple ejemplo ayudaría a demostrarlo. Supongamos que tiene dos implementaciones de direcciones I Address1 y Address2. Cada uno se guarda en su propia tabla, tblAddress1 y tblAddress2. Cuando intenta cargar su objeto Field, todo lo que sabe NHibernate es que tiene algo que implementa IAddress, no sabe qué implementación se mantuvo. ¿Cómo sabría qué mapeo usar para recuperar el objeto hijo para cualquier campo dado?

Estoy seguro de que hay más complicaciones, pero este ejemplo muestra por qué debe tener una asignación para el tipo exacto de objeto que ha declarado.

0

Si está interesado en desacoplar completamente su ORM de su capa de dominio, y hacer referencia a interfaces en toda su capa de datos en lugar de especificar clases concretas, puede implementar un EmptyInterceptor para correlacionar los dos.

Ver mi respuesta here.

Cuestiones relacionadas