【问题标题】:Explicit construction of entity type '' in query is not allowed不允许在查询中显式构造实体类型“”
【发布时间】:2016-03-16 04:45:44
【问题描述】:

我收到以下错误

Explicit construction of entity type '...TableClassName' in query is not allowed.

Server stack trace: 
   at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
   at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

这是我的代码。

tgdd = new List<TableClassName>();
    context.DeferredLoadingEnabled = false;
    var t = context.TableClassName.Where(...)
                                  .GroupBy(g => new { g.Date, g.UserID })
                                  .Select(g => new TableClassName
                                  {
                                        PK = 1,
                                        Date = Convert.ToDateTime(g.Key),
                                        Counted = g.Sum(x => x.Counted),
                                        Time = g.Sum(x => x.Time),
                                        MaxHR = g.Max(x => x.MaxHR),
                                        PeakCal = g.Max(x => x.PeakCal),
                                        PowerIndex = (g.Sum(x => x.PowerIndex)),
                                        Target = g.Max(x => x.Target),
                                        RepTotal = g.Sum(x => x.RepTotal),
                                        Lifted = g.Sum(x => x.Lifted),
                                        UserID = Convert.ToInt64(g.Key)
                                   }).ToList();

                        foreach (TableClassName r in t)
                        {
                            tgdd.Add(r);
                        }

我没有语法错误。这是一个网络服务。我在调用它时遇到了问题。

【问题讨论】:

    标签: c# linq .net-4.0


    【解决方案1】:

    考虑以下几点:

    context.DeferredLoadingEnabled = false; 
    tgdd = context.TableClassName.Where(...) 
                                 .GroupBy(g => new { g.Date, g.UserID })
                                 .AsEnumerable() 
                                 .Select(g => new TableClassName 
                                 { 
                                       PK = 1, 
                                       Date = Convert.ToDateTime(g.Key), 
                                       Counted = g.Sum(x => x.Counted), 
                                       Time = g.Sum(x => x.Time), 
                                       MaxHR = g.Max(x => x.MaxHR), 
                                       PeakCal = g.Max(x => x.PeakCal), 
                                       PowerIndex = (g.Sum(x => x.PowerIndex)), 
                                       Target = g.Max(x => x.Target), 
                                       RepTotal = g.Sum(x => x.RepTotal), 
                                       Lifted = g.Sum(x => x.Lifted), 
                                       UserID = Convert.ToInt64(g.Key) 
                                  }).ToList(); 
    

    通过在 Group 操作之后调用 AsEnumerable,我们将投影强制投射到客户端的自定义类型中,而不是在服务端不知道您的自定义类型的服务器中。此外,通过在查询上调用 ToList,您无需遍历结果并将它们添加到另一个列表中。只需将第一个 ToList 的结果直接分配给您要返回的对象即可。

    【讨论】:

    • 您需要非常小心如何将其转换为 SQL。由于您现在正在内存中而不是 DB 中进行聚合,因此它就像是对 SELECT DISTINCT data, userID FROM TableName 的调用,然后是对与第一次调用的结果匹配的每组行的另一个调用,这可能意味着替换单个数以千计的数据库调用(我不止一次在我身边偷偷摸摸过)。请参阅我在stackoverflow.com/a/11805099/400547 的回答以对此进行检查。
    【解决方案2】:

    我使用匿名类型来解决这个问题(删除了关键字“new”之后的 TableClassName)。

    然后我遇到了另一个问题,使用我的 TableClassName 遍历 var(由于 var 中的内容是匿名的而导致错误)。

    我遍历 var,使用 var,然后将每个 var 的内容一一提取到我的对象中,然后按原意将对象添加到我的列表中。这是我的代码。

    foreach (var v in t)
    {
        TableClassName tgData = new TableClassName();
        tgData.PK = v.PK;
        tgData.Date = v.Date;
        tgData.Counted= v.Counted;
        tgData.Time = v.Time;
        tgData.MaxHR = v.MaxHR;
        tgData.PeakCal = v.PeakCal;
        tgData.PowerIndex = v.PowerIndex;
        tgData.Target = v.Target;
        tgData.RepTotal = v.RepTotal;
        tgData.Lifted = v.Lifted;
        tgData.UserID = v.UserID;
        tgdd.Add(tgData);
    }
    

    希望这对某人有所帮助。

    【讨论】:

      【解决方案3】:

      尝试从 LINQ 查询中分离出“新 TableClassName”部分。

      你可能想看看这个帖子:

      http://social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/thread/1ce25da3-44c6-407d-8395-4c146930004b/

      “实体的使用模式是它们在查询之外创建并通过 DataContext 插入表中,然后通过查询检索,而不是由查询创建”

      【讨论】:

      • 关于如何将它们分开的任何提示?我是 LINQ 的新手。
      【解决方案4】:

      这是可能的,如果你创建一个没有 [Table]-Attribute 的新派生类,如下所示:

      public class TableClassNameLocal : TableClassName
      {
      }
      

      然后您可以在选择中创建“TableClassNameLocal”的实例。将新实例直接转换为“TableClassName”,它将起作用!

      result = new List<TableClassName>();
      context.DeferredLoadingEnabled = false;
      var t = context.TableClassName.Where(...)
                                    .GroupBy(g => new { g.Date, g.UserID })
                                    .Select(g => (TableClassName)new TableClassNameLocal
                                    {
                                          PK = 1,
                                          Date = Convert.ToDateTime(g.Key),
                                          Counted = g.Sum(x => x.Counted),
                                          Time = g.Sum(x => x.Time),
                                          MaxHR = g.Max(x => x.MaxHR),
                                          PeakCal = g.Max(x => x.PeakCal),
                                          PowerIndex = (g.Sum(x => x.PowerIndex)),
                                          Target = g.Max(x => x.Target),
                                          RepTotal = g.Sum(x => x.RepTotal),
                                          Lifted = g.Sum(x => x.Lifted),
                                          UserID = Convert.ToInt64(g.Key)
                                     }).ToList();
      

      【讨论】:

        【解决方案5】:

        这对我有用:

          var roles = (from r in roleNames
                                            join rm in DataContext.FMC_RoleMaps on r equals rm.RoleName_old
                                            select new
                                            {
                                                dnnUser.UserID,
                                                rm.RoleID
                                            }
                                                   );
                               foreach (var userRole in roles)
                               {
                                   var newrole = new UserRole()
                                                     {
                                                         RoleID = userRole.RoleID,
                                                         UserID = userRole.UserID
                                                     };
                                   DataContext.UserRoles.InsertOnSubmit(newrole);
                               }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多