2010-01-04 16 views
6

tengo la clase siguiente:Nhibernate haciendo actualizaciones en select?

public class Product 
{ 
    public virtual Guid Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual Decimal PricePerMonth { get; set; } 
    public virtual BillingInterval DefaultBillingInterval { get; set; } 
    public virtual string AdditionalInfo { get; set; } 
} 

y el mapeo se ve así:

<class name="Product" table="Products"> 
    <id name="Id" column="ProductId"> 
     <generator class="guid.comb"/> 
    </id> 
    <property name="Name" column="ProductName" not-null="true" type="String" /> 
    <property name="PricePerMonth" column="PricePerMonth" not-null="true" type="Decimal" /> 
    <property name="DefaultBillingInterval" type="int" not-null="true" /> 
    <property name="AdditionalInfo" type="string" not-null="false" /> 
</class> 

utilizo una clase Repository<T> con el método siguiente (Session es una propiedad que devuelve la sesión actual):

public IEnumerable<T> FindAll(DetachedCriteria criteria) 
{ 
    return criteria.GetExecutableCriteria(Session).List<T>(); 
} 

Ahora cuando hago lo siguiente (la sesión es la misma sesión utilizada en el repositorio):

La declaración de compromiso está allí, porque utilizo una capa de servicio que automáticamente confirma cada transacción si no se producen errores. Me acaba de derrumbarse mi capa de servicio aquí para una visualización más fácil ..

Mi método ToDTOs simplemente convierte a un DTO:

private IEnumerable<ProductDTO> ToDTO(IEnumerable<Product> products) 
{ 
    return products.Select(x => new ProductDTO() 
    { 
     Id = x.Id, 
     Name = x.Name, 
     PricePerMonth = x.PricePerMonth, 
     AdditionalInfo = x.AdditionalInfo 
    }).ToList(); 
} 

Mi registro nhibernate muestra el siguiente resultado:

2010-01-04 19:13:11,140 [4] DEBUG NHibernate.SQL - SELECT ... From Products ... 
2010-01-04 19:13:11,237 [4] DEBUG NHibernate.SQL - UPDATE Products ... 
2010-01-04 19:13:11,548 [4] DEBUG NHibernate.SQL - UPDATE Products ... 
... 

Así, seleccionando los productos emite una declaración de actualización para cada producto devuelto cuando la sesión se compromete, aunque no se ha modificado nada en los productos.

Alguna idea?

+0

¿Es esto * realmente * cómo se implementa la entidad? No te creo –

+0

Es ... Es cierto, tenía una lista de pedidos a los que se adjuntó el producto, pero eliminé esta lista, tanto de la clase como de la asignación (como se muestra aquí) y es el mismo resultado. Mi confusión es aún más profunda por el hecho de que esto no le sucede a mis otras entidades ... –

Respuesta

7

Solo tuve este efecto cuando tuve una entidad que no devuelve el mismo valor de la propiedad que el valor que se le ha asignado. Luego es tratado como sucio por NH.

Ejemplo:

class Foo 
{ 
    private string name; 

    public string Name 
    { 
    // does not return null when null had been set 
    get { return name ?? "No Name"; } 
    set { name = value; } 
    } 

} 

Ésta es la forma en que iba a escribir el archivo de asignación.

<class name="Product" table="Products"> 
    <id name="Id" column="ProductId"> 
     <generator class="guid.comb"/> 
    </id> 
    <property name="Name" column="ProductName" not-null="true" /> 
    <property name="PricePerMonth" not-null="true" /> 
    <property name="DefaultBillingInterval" not-null="true" /> 
    <property name="AdditionalInfo" /> 
</class> 

No necesita especificar tipos. Ellos están determinados por NHibernate en tiempo de ejecución.

+0

Aha, ¿entonces debe ser la enumeración BillingInterval la que está causando el problema ya que está mapeada como una int? ¿Cómo mapeo una enumeración (respaldada por un int) sin que ocurran las instrucciones de actualización? –

+0

No necesita especificar ningún tipo al asignar enumeraciones. –

+0

¿Funciona esto incluso cuando la base de datos almacena DefaultBillingInterval como smallint (los valores enum tienen los valores enteros 3,6,12)? –

1

Publicación anterior, pero tal vez esto ayude a alguien en el futuro.

Tengo una biblioteca de clases C# Repository de datos (Oracle como la base de datos). El valor de la tabla era NULL pero en mi repo el valor se definió como Decimal y debería haber sido? Decimal. Eso corrigió este problema de actualización cuando se ejecutaba una selección.

+1

Otro escenario donde puede obtener una ACTUALIZACIÓN imprevista es cuando se agrega una nueva propiedad a la asignación de base de datos y se lee un registro de una base de datos creada con la versión anterior de la asignación. –

+0

James, es bueno saberlo! –

Cuestiones relacionadas