37 votes

La construction explicite du type d'entité '###' dans la requête n'est pas autorisée

Im essayant d'instance une entité appelée "Produccion" de LINQDataContext de cette manière:

  Demo.View.Data.PRODUCCION pocoProduccion = (from m in db.MEDICOXPROMOTORs
                                             join a in db.ATENCIONs on m.cmp equals a.cmp
                                             join e in db.EXAMENXATENCIONs on a.numeroatencion equals e.numeroatencion
                                             join c in db.CITAs on e.numerocita equals c.numerocita
                                             where e.codigo == codigoExamenxAtencion
                                             select new Demo.View.Data.PRODUCCION
                                             {
                                                 cmp = a.cmp,
                                                 bonificacion = comi,
                                                 valorventa = precioEstudio,
                                                 codigoestudio = lblCodigoEstudio.Content.ToString(),
                                                 codigopaciente = Convert.ToInt32(lblCodigoPaciente.Content.ToString()),
                                                 codigoproduccion = Convert.ToInt32(lblNroInforme.Content.ToString()),
                                                 codigopromotor = m.codigopromotor,
                                                 fecha = Convert.ToDateTime(DateTime.Today.ToShortDateString()),
                                                 numeroinforme = Convert.ToInt32(lblNroInforme.Content.ToString()),
                                                 revisado = false,
                                                 codigozona = (c.codigozona.Value == null ? Convert.ToInt32(c.codigozona) : 0),
                                                 codigoclinica = Convert.ToInt32(c.codigoclinica),
                                                 codigoclase = e.codigoclase,
                                             }
                                             ).FirstOrDefault();
 

Je reçois l'erreur suivante:

 System.NotSupportedException was caught
  Message="No se permite la construcción explícita del tipo de entidad 'Demo.View.Data.PRODUCCION' en una consulta."
  Source="System.Data.Linq"
  StackTrace:
       en System.Data.Linq.SqlClient.QueryConverter.VisitMemberInit(MemberInitExpression init)
       en System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)
       en System.Data.Linq.SqlClient.QueryConverter.Visit(Expression node)
       en System.Data.Linq.SqlClient.QueryConverter.VisitSelect(Expression sequence, LambdaExpression selector)
       en System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc)
       en System.Data.Linq.SqlClient.QueryConverter.VisitMethodCall(MethodCallExpression mc)
       en System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)
       en System.Data.Linq.SqlClient.QueryConverter.Visit(Expression node)
       en System.Data.Linq.SqlClient.QueryConverter.VisitFirst(Expression sequence, LambdaExpression lambda, Boolean isFirst)
       en System.Data.Linq.SqlClient.QueryConverter.VisitSequenceOperatorCall(MethodCallExpression mc)
       en System.Data.Linq.SqlClient.QueryConverter.VisitMethodCall(MethodCallExpression mc)
       en System.Data.Linq.SqlClient.QueryConverter.VisitInner(Expression node)
       en System.Data.Linq.SqlClient.QueryConverter.ConvertOuter(Expression node)
       en System.Data.Linq.SqlClient.SqlProvider.BuildQuery(Expression query, SqlNodeAnnotations annotations)
       en System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Execute(Expression query)
       en System.Data.Linq.DataQuery`1.System.Linq.IQueryProvider.Execute[S](Expression expression)
       en System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
       en Demo.View.InformeMedico.realizarProduccionInforme(Int32 codigoExamenxAtencion, Double precioEstudio, Int32 comi) en D:\cs_InformeMedico\app\InformeMedico.xaml.cs:línea 602
       en Demo.View.InformeMedico.UpdateEstadoEstudio(Int32 codigo, Char state) en D:\cs_InformeMedico\app\InformeMedico.xaml.cs:línea 591
       en Demo.View.InformeMedico.btnGuardar_Click(Object sender, RoutedEventArgs e) en D:\cs_InformeMedico\app\InformeMedico.xaml.cs:línea 683
  InnerException: 
 

Est-ce maintenant autorisé dans LINQ2SQL?

22voto

Martin Peck Points 8078

Les entités peuvent être créées en dehors des requêtes et insérées dans le magasin de données à l'aide d'un DataContext. Vous pouvez ensuite les récupérer à l'aide de requêtes. Cependant, vous ne pouvez pas créer d'entités dans le cadre d'une requête.

15voto

yo hal Points 1949

Je viens de trouver cette limitation est très ennuyeux, et aller à l'encontre de la tendance commune de pas à l'aide de SELECT * dans les requêtes.

Toujours avec c# anonyme types, il y a une solution de contournement, en allant chercher les objets dans un type anonyme, puis la copier dans le bon type.

Par exemple:

var q = from emp in employees where emp.ID !=0
select new {Name = emp.First + " " + emp.Last, EmployeeId = emp.ID }
var r = q.ToList();
List<User> users = new List<User>(r.Select(new User
   {
        Name = r.Name,
        EmployeeId = r.EmployeeId 
   }));

Et dans le cas lorsque nous traitons avec une valeur unique (comme dans la situation décrite dans la question), il est même plus facile, et nous avons juste besoin de copier directement les valeurs:

var q = from emp in employees where emp.ID !=0 
select new { Name = emp.First + " " + emp.Last, EmployeeId = emp.ID }
var r = q.FirstOrDefault();
User user = new User { Name = r.Name, EmployeeId = r.ID };

Si le nom de l'propriétés correspondent les colonnes de base de données, nous pouvons faire encore plus simple dans la requête, en faisant sélectionnez

var q = from emp in employees where emp.ID !=0 
select new { emp.First, emp.Last, emp.ID }

On pourrait aller de l'avant et d'écrire une expression lambda qui peut copier automatiquement, basée sur le nom de la propriété, sans avoir besoin de spécifier les valeurs explicitement.

15voto

pbz Points 2468

Voici une autre solution:

  1. Faire une classe qui dérive de votre LINQ to SQL classe. Je suis en supposant que le L2S classe que vous voulez retourner à l'Ordre de:

    internal class OrderView : Order { }
    
  2. Maintenant écrire la requête de cette façon:

    var query = from o in db.Order
                select new OrderView // instead of Order
                {
                   OrderID = o.OrderID,
                   OrderDate = o.OrderDate,
                   // etc.
                };
    
  3. Fonte le résultat dans l'Ordre, comme ceci:

    return query.Cast<Order>().ToList(); // or .FirstOrDefault()
    
  4. (ou utiliser quelque chose de plus raisonnable, comme BLToolkit / LINQ to DB)

Note: je n'ai pas testé pour voir si le suivi fonctionne ou pas; ça marche pour récupérer des données, qui est ce dont j'avais besoin.

12voto

mimo Points 408

J'ai trouvé que si vous faites un .ToList () sur la requête avant d'essayer de construire de nouveaux objets, cela fonctionne

9voto

leppie Points 67289

Je suis juste tombé sur le même problème.

J'ai trouvé une solution très simple.

 var a = att as Attachment;

Func<Culture, AttachmentCulture> make = 
    c => new AttachmentCulture { Culture = c };

var culs = from c in dc.Cultures
           let ac = c.AttachmentCultures.SingleOrDefault( 
                                           x => x.Attachment == a)
           select ac == null ? make(c) : ac;

return culs;
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X