Linq to sql 不允许在查询中显式构造实体类型“”。

Linq to sql 不允许在查询中显式构造实体类型“”。,linq-to-sql,Linq To Sql,使用Linq命令和Linq To SQL datacontext,我试图以以下方式从我的datacontext中实例化一个名为Produccion的实体: 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.nume

使用Linq命令和Linq To SQL datacontext,我试图以以下方式从我的datacontext中实例化一个名为Produccion的实体:

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();
执行上述代码时,我得到以下错误,其中包括堆栈跟踪:

System.NotSupportedException was caught
  Message="The explicit construction of the entity type 'Demo.View.Data.PRODUCCION' in a query is not allowed."
  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: 

现在在LINQ2SQL中允许这样做吗?

可以在查询之外创建实体,并使用DataContext将其插入到数据存储中。然后可以使用查询检索它们。但是,您不能在查询中创建实体。

我刚刚遇到了同样的问题

我找到了一个非常简单的解决办法

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;

在70-515《使用Microsoft.NET Framework 4开发Web应用程序-自定步调培训工具包》一书中,第638页提供了将结果输出到强类型对象的示例:

    IEnumerable<User> users = from emp in employees where emp.ID !=0
    select new User
    {
    Name = emp.First + " " + emp.Last,
    EmployeeId = emp.ID
    }

Mark Pecks的建议似乎与本书相矛盾——然而,对于我来说,这个例子仍然显示了上述错误,让我有些困惑。这与版本差异有关吗?欢迎任何建议。

我发现这个限制非常烦人,并且与查询中不使用SELECT*的常见趋势背道而驰

对于c匿名类型,仍然有一种解决方法,将对象提取到匿名类型中,然后将其复制到正确的类型中

例如:

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 
   }));
如果属性的名称与数据库列匹配,我们可以通过执行select在查询中执行更简单的操作

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

可以编写一个lambda表达式,该表达式可以根据属性名自动复制,而无需明确指定值

我发现,如果您在尝试构造新对象之前对查询执行.ToList操作,它就会工作

以下是另一种解决方法:

创建一个从LINQ到SQL类派生的类。我假设您要返回的L2S类是Order:

internal class OrderView : Order { }
现在按以下方式编写查询:

var query = from o in db.Order
            select new OrderView // instead of Order
            {
               OrderID = o.OrderID,
               OrderDate = o.OrderDate,
               // etc.
            };
将结果重新按顺序排列,如下所示:

return query.Cast<Order>().ToList(); // or .FirstOrDefault()
或者使用更合理的方法,比如BLToolkit/linqtodb


注意:我还没有测试跟踪是否有效;它用于检索数据,这正是我所需要的。

我构造了一个匿名类型,使用IEnumerable保留延迟执行,然后重新构造datacontext对象。Employee和Manager都是datacontext对象:

    var q = dc.Employees.Where(p => p.IsManager == 1)
            .Select(p => new { Id = p.Id, Name = p.Name })
            .AsEnumerable()    
            .Select(item => new Manager() { Id = item.Id, Name = item.Name });

我为这个问题找到了另一种解决方法,它甚至可以让您将结果保留为IQueryale,因此在您希望查询像ToList方法一样执行之前,它实际上不会执行查询

所以linq不允许您创建实体作为查询的一部分?您可以将该任务转移到数据库本身,并创建一个函数来获取所需的数据。将函数导入数据上下文后,只需将结果类型设置为所需的类型


当我不得不编写一段代码来生成一个IQueryable时,我发现其中的项实际上不存在于包含t的表中。

如何将返回查询中的select值传递给实体,我的意思是不使用成员,就像varreturningqueryasproductionentity?select写为selectac可能更好一些??makec;非常好的解决方案-谢谢!知道为什么不这样做是不允许的吗?@Whisk-如果你还感兴趣的话,我发现-“…手动构造实体实例,因为投影会使用可能存在格式错误的对象污染缓存…”如果用户不是DataContext的一部分,则上面的示例有效。但这会丢失延迟执行。我发现的唯一解决方案是不延迟执行。选择p=>new{anonymouscolumns}.ToList.Selectp=>newtmodel{Col1=p.Col1等}太棒了!虽然我不需要回溯,但我同意这是一个很好的解决方案!如果有技术上的原因,我不应该投射到实体类上,那没关系,我不会,但是谁想用完全相同的形状重新定义一个可能很长的新类呢?没有人,那是谁。此解决方案无需显式重新定义即可解决此问题。干得好,pbz,搞定了。我同意限制很烦人。然而,在您的解决方案中调用ToList会将结果放入内存中,这对于大数据集来说可能是不可取的?
    var q = dc.Employees.Where(p => p.IsManager == 1)
            .Select(p => new { Id = p.Id, Name = p.Name })
            .AsEnumerable()    
            .Select(item => new Manager() { Id = item.Id, Name = item.Name });