当前位置:  开发笔记 > 编程语言 > 正文

简单的linq to sql没有支持的SQL转换

如何解决《简单的linqtosql没有支持的SQL转换》经验,为你挑选了1个好方法。

我在BlogRepository中有这个

public IQueryable GetPosts()
    {
        var query = from p in db.Posts
                    let categories = GetCategoriesByPostId(p.PostId)
                    let comments = GetCommentsByPostId(p.PostId)
                    select new Subnus.MVC.Data.Model.Post
                    {
                        Categories = new LazyList(categories),
                        Comments = new LazyList(comments),
                        PostId = p.PostId,
                        Slug = p.Slug,
                        Title = p.Title,
                        CreatedBy = p.CreatedBy,
                        CreatedOn = p.CreatedOn,
                        Body = p.Body
                    };
        return query;
    }

public IQueryable GetCommentsByPostId(int postId)
    {
        var query = from c in db.Comments
                    where c.PostId == postId
                    select new Subnus.MVC.Data.Model.Comment
                    {
                        Body = c.Body,
                        EMail = c.EMail,
                        Date = c.CreatedOn,
                        WebSite = c.Website,
                        Name = c.Name
                    };

        return query;
    }

private IQueryable GetCategoriesByPostId(int postId)
    {
        var query = from c in db.Categories
                    join pcm in db.Post_Category_Maps on c.CategoryId equals pcm.CategoryId
                    where pcm.PostId == postId
                    select new Subnus.MVC.Data.Model.Category
                    {
                        CategoryId = c.CategoryId,
                        Name = c.Name
                    };
        return query;
    }

当我适用这个过滤器

namespace Subnus.MVC.Data
{
 public static class BlogFilters
 {
    public static IQueryable WherePublicIs(this IQueryable qry,bool state)
    {

        return from p in qry
               where p.IsPublic == state
               select p;
    }
 }

}

如果该帮助命名空间Subnus.MVC.Data,则所有这些都位于相同的命名空间中

当我尝试这样做

public class BlogService : IBlogService
{
...
    public IList GetPublicPosts()
    {
         return repository.GetPosts().WherePublicIs(true).ToList();
    }
 ...
 }

这是在命名空间Subnus.MVC.Service中它抛出错误

Method 'System.Linq.IQueryable`1[Subnus.MVC.Data.Model.Comment] GetCommentsByPostId(Int32)' has no supported translation to SQL.

Bryan Watts.. 25

GetCommentsByPostId在最终的表达树中调用.组成时BlogService.GetPublicPosts,该树将转换为SQL.

在转换期间,它只是一个方法调用,仅此而已.Linq to Sql理解某些方法调用,而你的不是其中之一.因此错误.

从表面上看,这似乎应该有效.您编写可重用查询并从其他查询中编写它们.但是,你实际上说的是:"在处理数据库服务器上的每一行时,调用这个方法",这显然是做不到的.它需要一个IQueryable并返回一个这一事实IQueryable并不会使它变得特别.

想想这样说:您传递postIdGetCategoriesByPostId.在拥有a之前postId,不能调用该方法,并且在查询服务器上之前没有其中之一.

您可能需要Expression<>为子查询定义公共实例并使用组合中的实例.我没有想过这会是什么样子,但它肯定是可行的.

编辑:

如果你更换

let categories = GetCategoriesByPostId(p.PostId)
let comments = GetCommentsByPostId(p.PostId)
...
Categories = new LazyList(categories),
Comments = new LazyList(comments),

Categories = new LazyList(GetCategoriesByPostId(p.PostId)),
Comments = new LazyList(GetCommentsByPostId(p.PostId)),

查询将不再抛出异常.

这是因为let声明范围变量,它们在每行的范围内.必须在服务器上计算它们.

但是,预测允许您在任务中放置任意代码,然后在客户端上构建结果时执行.这意味着将调用这两种方法,每种方法都会发出自己的查询.



1> Bryan Watts..:

GetCommentsByPostId在最终的表达树中调用.组成时BlogService.GetPublicPosts,该树将转换为SQL.

在转换期间,它只是一个方法调用,仅此而已.Linq to Sql理解某些方法调用,而你的不是其中之一.因此错误.

从表面上看,这似乎应该有效.您编写可重用查询并从其他查询中编写它们.但是,你实际上说的是:"在处理数据库服务器上的每一行时,调用这个方法",这显然是做不到的.它需要一个IQueryable并返回一个这一事实IQueryable并不会使它变得特别.

想想这样说:您传递postIdGetCategoriesByPostId.在拥有a之前postId,不能调用该方法,并且在查询服务器上之前没有其中之一.

您可能需要Expression<>为子查询定义公共实例并使用组合中的实例.我没有想过这会是什么样子,但它肯定是可行的.

编辑:

如果你更换

let categories = GetCategoriesByPostId(p.PostId)
let comments = GetCommentsByPostId(p.PostId)
...
Categories = new LazyList(categories),
Comments = new LazyList(comments),

Categories = new LazyList(GetCategoriesByPostId(p.PostId)),
Comments = new LazyList(GetCommentsByPostId(p.PostId)),

查询将不再抛出异常.

这是因为let声明范围变量,它们在每行的范围内.必须在服务器上计算它们.

但是,预测允许您在任务中放置任意代码,然后在客户端上构建结果时执行.这意味着将调用这两种方法,每种方法都会发出自己的查询.

推荐阅读
pan2502851807
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有