2010-08-19 3 views
0

J'ai une classeLINQ to NHibernate ne renvoie pas de données adéquates

public class Item : IItem 
{ 
    public virtual Guid Id { get; set; } 
    public virtual string Name { get; set; } 
    public virtual bool IsActive { get; set; } 
} 
public interface IItem 
{ 
    Guid Id { get; set; } 
    string Name { get; set; } 
    bool IsActive { get; set; } 
} 

public class ItemMap : ClassMap<Item> 
{ 
    public ItemMap() 
    { 
     Id(x => x.Id); 
     Map(x => x.Name); 
     Map(x => x.IsActive); 
    } 
} 

Dans ma base de données que j'ai créé cinq articles. Trois ont l'indicateur IsActive défini sur true et deux qui l'ont défini sur false.

Lorsque vous utilisez l'interface renvoie les cinq éléments:

 var q = from i in session.Linq<IItem>() 
       where i.IsActive == true 
       select i; 

Cependant, lorsque vous utilisez la classe concrète, il renvoie les trois éléments appropriés:

 var q = from i in session.Linq<Item>() 
       where i.IsActive == true 
       select i; 

EDIT
j'ai serait J'aime retourner une interface, parce que j'ai lu que je devrais retourner des classes non concrètes. S'il vous plaît noter qu'en réalité, ces requêtes Linq sont dans un référentiel dans un projet différent (dans le cas où cela devient une application Web ou WPF)

+0

Votre dernière phrase n'a aucun sens. Vous pouvez très bien sous-classer 'Item' et toujours utiliser le type' Item' pour accéder aux instances de la sous-classe. – Timwi

+0

@Timwi, vous avez raison, je vais modifier pour transmettre correctement l'intention –

Répondre

1

Cela ressemble à un bogue dans l'ancien fournisseur linq contrib.

Essayez avec NHibernate 3, cela fonctionne comme prévu.

+0

Merci, @Diego qui a fonctionné. Il a cependant fallu un peu de course pour reconstruire les assemblages. http://stackoverflow.com/questions/2349400/how-to-get-fluent-nhibernate-working-with-nhibernate-3-x –

0

Je crois que vous aurez besoin de mapper IItem au lieu de la classe d'objet concrète pour avoir ce travail correctement.

0

Les choses que vous pouvez essayer:

  • Au lieu de

    public class ItemMap : ClassMap<Item> 
    

    utilisation

    public class ItemMap : ClassMap<IItem> 
    
  • jeter simplement les objets qui sont retournés:

    var q = from i in session.Linq<Item>() 
         where i.IsActive == true 
         select (IItem)i; 
    
0

Je ne pense pas que vous ayez à vous inquiéter des requêtes par rapport aux types de béton, c'est très bien. Ayez juste votre méthode de dépôt de retour une interface. Avoir du sens?

public IItem GetItem(int id) 
{ 

    var item = from i in session.Linq<Item>() 
       where i.IsActive == true 
       select i; 

    return item; 

} 

Cela vous permettra de interroger le travail comme il devrait et laisser tout votre travail de code dépendant contre l'interface, ce qui est tout ce que vous avez vraiment besoin de l'interface de toute façon.

0

J'ai posté un similar issue here et j'ai fini par perdre hibernate (pour des raisons sans rapport cependant). Je ne pense pas que LINQ soit vraiment "fini" en hibernation pour le moment, il y a encore des méthodes, c'est-à-dire Enumerable() qui lancent une exception non implémentée. Cependant, pour répondre à votre question, j'ai trouvé que je devais utiliser des classes concrètes et non des interfaces car il n'y a pas de fichier * .hbm.xml pour l'interface, donc hibernate ne sait pas comment mapper l'interface à sa table respective . Comme quelqu'un l'a dit dans mon article, je prends probablement un peu trop loin ce couplage lâche, car vous ne devriez utiliser que le couplage lâche et l'inversion du contrôle dans des zones de changements potentiels - mais les modèles de base de données changent beaucoup.

Je pense que la clé ici est de s'assurer que votre domaine d'activité est dans son propre assembly "MyBusiness.Domain" et que tous les projets s'y réfèrent.Tous ces projets auront alors des interfaces spécifiées (design by contract) et les classes concrètes et injectées en utilisant quelque chose comme Ninject, de cette façon vous pouvez instancier de nouvelles classes dans votre domaine métier et aussi longtemps qu'elles implémenteront les interfaces pertinentes que vos projets peuvent utiliser.

Comme vous pouvez le voir, je ne suis pas un expert en la matière ... pour l'instant ... mais je pense que cette façon de développer un logiciel fonctionne fondamentalement correctement, et c'est assez compliqué au démarrage!

Questions connexes