J'ai un projet d'application d'affaires Silverlight mis en place, avec ces codes.NHibernate.Linq, services WCF RIA, erreur bizarre
J'ai cette classe de domaine:
public class BaseDomain
{
public virtual Guid Id { get; set; }
public virtual DateTime CreatedOn { get; set; }
}
public class Sector : BaseDomain
{
public virtual string Code { get; set; }
public virtual string Name { get; set; }
}
Le domaine des objets mapping a été mis en place et fonctionne bien.
Le J'ai cette classe DTO:
public class SectorDto : BaseDto
{
[Key]
public virtual Guid Id { get; set; }
public virtual DateTime CreatedOn { get; set; }
public virtual string Code { get; set; }
public virtual string Name { get; set; }
public SectorDto()
{
}
public SectorDto(Sector d)
{
Id = d.Id;
CreatedOn = d.CreatedOn;
Code = d.Code;
Name = d.Name;
}
}
DTO est utilisé pour aplatir l'objet et assurez-vous pas de relations inutiles d'être sérialisés et transféré sur le fil.
Alors j'ai ce RIA DomainService (il existe plusieurs variantes de la méthode GetSectors(), je vous expliquerai plus tard):
[EnableClientAccess]
public class OrganizationService : BaseDomainService
{
public IQueryable<SectorDto> GetSectors1()
{
return GetSession().Linq<Sector>()
.Select(x => Mapper.Map<Sector, SectorDto>(x));
}
public IQueryable<SectorDto> GetSectors2()
{
return GetSession().Linq<Sector>().ToList()
.Select(x => new SectorDto(x)).AsQueryable();
}
public IQueryable<SectorDto> GetSectors3()
{
return GetSession().Linq<Sector>().Select(x => new SectorDto(x));
}
public IQueryable<SectorDto> GetSectors4()
{
return GetSession().Linq<Sector>().Select(x => new SectorDto() {
Id = x.Id, CreatedOn = x.CreatedOn, Name = x.Name, Code = x.Code });
}
}
BaseDomainService est juste une classe parent qui fournit le traitement pour la session NHibernate. Je mets la session à vivre par requête web.
Puis je brancher le service à un DataGrid (Silverlight Toolkit) dans une page XAML:
var ctx = new App.Web.Services.OrganizationContext();
SectorGrid.ItemsSource = ctx.SectorDtos;
ctx.Load(s.GetSectors1Query());
Lorsque vous appelez les différentes méthodes, j'ai ces résultats:
Méthode GetSectors1 ( génère une exception "L'opération de chargement a échoué pour la requête 'GetSectors1'. Impossible de convertir l'objet de type NHibernate.Linq.Expressions.EntityExpression 'en type' NHibernate.Linq.Expressions.CollectionAccessExpression '. ".
C'est la meilleure façon que j'essaie de faire. Je veux utiliser la bibliothèque AutoMapper pour mapper automatiquement la classe de domaine au DTO. Je suis assez positif que le problème ne provient pas de l'AutoMapper puisque j'obtiens aussi l'erreur si j'appelle une méthode de la méthode anonyme passée dans Select, par exemple.
GetSession().Linq<Sector>().Select(x => CustomMap(x))
.Méthode GetSectors2() affiche les données correctement de la grille, mais cela va à l'encontre du but d'utiliser IQueryable, l'appel ne serait pas paresseux évalué.
La méthode GetSectors3() récupère les données, mais uniquement l'ID et le CreatedOn qui se trouvent dans la classe parente BaseDomain. Le code et le nom sont tous les deux null.
La méthode GetSectors4() récupère les données correctement et paresseusement évalué, mais je ne veux pas mapper manuellement mon domaine à DTO chaque fois comme ça!
Alors qu'est-ce qui donne? Les résultats sont si loin que ce que j'attendais! Une idée sur la façon de faire ce travail? Aucun conseil?
J'apprécie toute aide, je suis presque perdu. Merci beaucoup.
Avez-vous essayé d'utiliser HQL ou l'API Criteria au lieu de Linq? Est-ce que ça marche alors? –
J'ai besoin de LINQ pour obtenir le résultat comme IQueryable, afin que le contrôle RIA Service DomainDataSource puisse gérer automatiquement la pagination, le filtrage, le tri, etc. – Ikhwan
Avez-vous essayé le fournisseur Linq dans le tronc NHibernate (par rapport au fournisseur NHContrib Linq que vous utilisez? à présent)? –