编译

时间:2015-07-17 12:57:40

标签: c# linq

我有超过100个编译查询,但这一个导致问题。 这是我精确编译的查询:

public static Func<DatabaseDataContext, int, string, int, byte, NameCommentPageResult>
           GetNameComments = CompiledQuery.Compile((DatabaseDataContext db, int NameId, string UserId, int Start, byte Count)
        => new NameCommentPageResult
        {
            Count = db.NameComments.Count(q => q.NameId == NameId && q.VerifiedBy != "-1"),
            Name = db.Names.First(n => n.ID == NameId).Name1,
            Comments = db.NameComments.Where(c => c.NameId == NameId && c.VerifiedBy != "-1").Select(c => new NameCommentResult
            {
                Datetime = c.Datetime,
                Id = c.Id,
                NameId = c.NameId,
                UserId = c.UserId,
                UserVoted = db.NameCommentVotes.Any(v => v.UserId == UserId && v.CommentId == c.Id),
                UserDisplayName = db.AspNetUserClaims.Any(cl => cl.ClaimType == "DisplayName" && cl.ClaimValue != "" && cl.User_Id == c.UserId) ? db.AspNetUserClaims.Where(cl => cl.ClaimType == "DisplayName" && cl.ClaimValue != "" && cl.User_Id == c.UserId).First().ClaimValue : db.AspNetUsers.Where(u => u.Id == c.UserId).First().UserName,
                UserPhoto = db.AspNetUserClaims.Where(cl => cl.User_Id == c.UserId && cl.ClaimType == "Image").SingleOrDefault().ClaimValue,
            }).OrderByDescending(o => o.Datetime).Skip(Start - 1).Take(Count).ToArray()
        });

我收到错误:

  

值不能为空。   参数名称:值

     

描述:执行当前Web请求期间发生了未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。   异常详细信息:System.ArgumentNullException:Value不能为null。   参数名称:值

但是当我运行相同的代码而不编译它时,它运行正常,问题是什么?

这很好用:

int Start = 1; byte Count = 10; int NameId = 100; 
    using (DatabaseDataContext db = new DatabaseDataContext())
                {
                    //Result = _Names.Comments.GetNameComments(db, Id, User == null ? "" : User.Id, 1, (byte)10);
                    Result = new NameCommentPageResult
                       {
                           Count = db.NameComments.Count(q => q.NameId == Id && q.VerifiedBy != "-1"),
                           Name = db.Names.First(n => n.ID == Id).Name1,
                           Comments = db.NameComments.Where(c => c.NameId == Id && c.VerifiedBy != "-1").Select(c => new NameCommentResult
                           {
                               Datetime = c.Datetime,
                               Id = c.Id,
                               NameId = c.NameId,
                               UserId = c.UserId,
                               UserVoted = db.NameCommentVotes.Any(v => v.UserId == User.Id && v.CommentId == c.Id),
                               UserDisplayName = db.AspNetUserClaims.Any(cl => cl.ClaimType == "DisplayName" && cl.ClaimValue != "" && cl.User_Id == c.UserId) ? db.AspNetUserClaims.Where(cl => cl.ClaimType == "DisplayName" && cl.ClaimValue != "" && cl.User_Id == c.UserId).First().ClaimValue : db.AspNetUsers.Where(u => u.Id == c.UserId).First().UserName,
                               UserPhoto = db.AspNetUserClaims.Where(cl => cl.User_Id == c.UserId && cl.ClaimType == "Image").SingleOrDefault().ClaimValue,
                           }).OrderByDescending(o => o.Datetime).Skip(Start - 1).Take(Count).ToArray()
                       };
                }

这就是Stack Trace:

  

[ArgumentNullException:Value不能为null。   参数名称:值]      System.Data.Linq.SqlClient.SqlJoin..ctor(SqlJoinType类型,SqlSource左,SqlSource右,SqlExpression cond,Expression sourceExpression)+1222094      System.Data.Linq.SqlClient.Visitor.VisitMultiset(SqlSubSelect sms)+324      System.Data.Linq.SqlClient.SqlVisitor.VisitSubSelect(SqlSubSelect ss)+91      System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node)+1014      System.Data.Linq.SqlClient.SqlVisitor.VisitExpression(SqlExpression exp)+15      System.Data.Linq.SqlClient.SqlVisitor.VisitNew(SqlNew sox)+186      System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node)+1205      System.Data.Linq.SqlClient.SqlVisitor.VisitExpression(SqlExpression exp)+15      System.Data.Linq.SqlClient.Visitor.VisitSelect(SqlSelect select)+128      System.Data.Linq.SqlClient.SqlVisitor.Visit(SqlNode node)+1110      System.Data.Linq.SqlClient.SqlProvider.BuildQuery(ResultShape resultShape,Type resultType,SqlNode node,ReadOnlyCollection`1 parentParameters,SqlNodeAnnotations annotations)+828      System.Data.Linq.SqlClient.SqlProvider.BuildQuery(表达式查询,SqlNodeAnnotations注释)+279      System.Data.Linq.SqlClient.SqlProvider.System.Data.Linq.Provider.IProvider.Compile(Expression query)+104      System.Data.Linq.CompiledQuery.ExecuteQuery(DataContext context,Object [] args)+203      System.Data.Linq.CompiledQuery.Invoke(TArg0 arg0,TArg1 arg1,TArg2 arg2,TArg3 arg3,TArg4 arg4)+223      comments.Page_Load(Object sender,EventArgs e)在g:\ Dropbox \ Projects \ NameBabies-New \ comments.aspx.cs:21      System.Web.UI.Control.LoadRecursive()+ 71      System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint,Boolean includeStagesAfterAsyncPoint)+3178

更新

这个有趣的代码解决了错误,但它不是正确的事情,任何人都可以建议做什么呢?

public static Func<DatabaseDataContext, int, string, int, byte, NameCommentPageResult>
               GetNameComments = CompiledQuery.Compile((DatabaseDataContext db, int NameId, string UserId, int Start, byte Count)
          db.Names.Select(s  => new NameCommentPageResult
            {
                Count = db.NameComments.Count(q => q.NameId == NameId && q.VerifiedBy != "-1"),
                Name = db.Names.First(n => n.ID == NameId).Name1,
                Comments = db.NameComments.Where(c => c.NameId == NameId && c.VerifiedBy != "-1").Select(c => new NameCommentResult
                {
                    Datetime = c.Datetime,
                    Id = c.Id,
                    NameId = c.NameId,
                    UserId = c.UserId,
                    UserVoted = db.NameCommentVotes.Any(v => v.UserId == UserId && v.CommentId == c.Id),
                    UserDisplayName = db.AspNetUserClaims.Any(cl => cl.ClaimType == "DisplayName" && cl.ClaimValue != "" && cl.User_Id == c.UserId) ? db.AspNetUserClaims.Where(cl => cl.ClaimType == "DisplayName" && cl.ClaimValue != "" && cl.User_Id == c.UserId).First().ClaimValue : db.AspNetUsers.Where(u => u.Id == c.UserId).First().UserName,
                    UserPhoto = db.AspNetUserClaims.Where(cl => cl.User_Id == c.UserId && cl.ClaimType == "Image").SingleOrDefault().ClaimValue,
                }).OrderByDescending(o => o.Datetime).Skip(Start - 1).Take(Count).ToArray()
            }).First());

我将=> new NameCommentPageResult编辑为db.Names.Select(s => new NameCommentPageResult并仅获得第一个结果。请注意,db.Names与我的查询无关,我可以使用db.AnyTableName代替

1 个答案:

答案 0 :(得分:1)

这是一个L2S错误,内部L2S代码以不受控制的方式崩溃这一事实很清楚。

那说查询子集合(这里:Comments)要么在它工作时很慢(SELECT N + 1),要么不受支持。可能在编译的查询中不支持它。编译的查询不支持某些结构。

可能由于性能问题,您不应该查询子集合。重写您的代码,以便不进行此操作。

因为您现在可能正在学习.NET:LINQ to SQL已经过时,并且ASPX页面被许多人认为是过时的(或者是最后的技术)。