2010-01-04 7 views
6

J'ai la classe suivante:Nhibernate faire des mises à jour sur 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; } 
} 

et la cartographie ressemble à ceci:

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

J'utilise une classe Repository<T> avec la méthode suivante (Session est une propriété qui retourne la session en cours):

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

Maintenant, lorsque je fais ce qui suit (la session est la même session utilisée dans le référentiel):L'instruction commit est présente, car j'utilise une couche de service qui valide automatiquement chaque transaction si aucune erreur ne s'est produite. Je viens écroulé ma couche de service ici pour faciliter la visualisation ..

Ma méthode ToDTOs convertit simplement 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(); 
} 

Mon journal de NHibernate montre la sortie suivante:

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 ... 
... 

Ainsi, en sélectionnant les produits qu'il émet une instruction de mise à jour pour chaque produit retourné lorsque la session est validée, même si rien n'a été changé dans les produits.

Des idées?

+0

Est-ce * vraiment * comment l'entité est implémentée? Je ne te crois pas. –

+0

C'est vrai ... J'avais une liste d'ordres auxquels le produit était attaché, mais j'ai enlevé cette liste, à la fois de la classe et du mapping (comme montré ici) et c'est le même résultat .. Ma confusion est encore plus profonde par le fait que cela n'arrive pas à mes autres entités .. –

Répondre

7

J'ai seulement eu cet effet quand j'avais une entité qui ne renvoie pas la même valeur de la propriété que la valeur qui lui a été assignée. Ensuite, il est considéré comme sale par NH.

Exemple:

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

} 

Voici comment j'écrire le fichier de mappage.

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

Vous n'avez pas besoin de spécifier de type. Ils sont déterminés par NHibernate lors de l'exécution.

+0

Aha, donc ce doit être l'enum BillingInterval qui cause le problème car il est mappé comme un int? Comment mapper une énumération (soutenue par un int) sans que les instructions de mise à jour ne se produisent? –

+0

Vous n'avez pas besoin de spécifier de type lors du mappage des énumérations. –

+0

Est-ce que cela fonctionne même lorsque la base de données stocke DefaultBillingInterval en tant que smallint (les valeurs enum ont les valeurs entières 3,6,12)? –

1

Plus ancien message, mais peut-être cela aidera quelqu'un sur la route.

J'ai une bibliothèque de classes C# Data Repository (Oracle comme base de données). La valeur de la table était NULL mais dans mon repo la valeur était définie comme Decimal et aurait dû être? Decimal. Cela a corrigé ce problème de mise à jour lors de l'exécution d'un select.

+1

Un autre scénario où vous pouvez obtenir une UPDATE inattendue est lorsqu'une nouvelle propriété a été ajoutée au mappage de base de données et qu'un enregistrement est lu à partir d'une base de données créée avec l'ancienne version du mappage. –

+0

James, bon à savoir! –

Questions connexes