Linq to sql 具有多个结果的Linq到SQL存储过程

Linq to sql 具有多个结果的Linq到SQL存储过程,linq-to-sql,multiple-resultsets,Linq To Sql,Multiple Resultsets,我们遵循下面的方法,使用LINQ to SQL从多个结果中获取数据 CREATE PROCEDURE dbo.GetPostByID ( @PostID int ) AS SELECT * FROM Posts AS p WHERE p.PostID = @PostID SELECT c.* FROM Categories AS c JOIN PostCategories AS pc

我们遵循下面的方法,使用LINQ to SQL从多个结果中获取数据

CREATE PROCEDURE dbo.GetPostByID
(
    @PostID int
)
AS
    SELECT    *
    FROM      Posts AS p
    WHERE     p.PostID = @PostID

    SELECT    c.*
    FROM      Categories AS c
    JOIN      PostCategories AS pc
    ON        (pc.CategoryID = c.CategoryID)
    WHERE     pc.PostID = @PostID
从DataContext继承的类中的调用方法应如下所示:

[Database(Name = "Blog")]
public class BlogContext : DataContext
{
    ... 

    [Function(Name = "dbo.GetPostByID")]
    [ResultType(typeof(Post))]
    [ResultType(typeof(Category))]
    public IMultipleResults GetPostByID(int postID)
    {
        IExecuteResult result = 
            this.ExecuteMethodCall(this, 
                  ((MethodInfo)(MethodInfo.GetCurrentMethod())), 
                  postID);

        return (IMultipleResults)(result.ReturnValue);
    }
}
请注意,该方法不仅使用映射到存储过程名称的函数属性进行修饰,还使用带有存储过程返回的结果集类型的ReturnType属性进行修饰。此外,该方法还返回IMultipleResults的非类型化接口:

public interface IMultipleResults : IFunctionResult, IDisposable
{
    IEnumerable<TElement> GetResult<TElement>();
}
公共接口IMultipleResults:IFunctionResult,IDisposable
{
IEnumerable GetResult();
}
因此,程序可以使用此接口检索结果:

BlogContext ctx = new BlogContext(...);

IMultipleResults results = ctx.GetPostByID(...);

IEnumerable<Post> posts = results.GetResult<Post>();

IEnumerable<Category> categories = results.GetResult<Category>();
BlogContext ctx=newblogcontext(…);
IMultipleResults=ctx.GetPostByID(…);
IEnumerable posts=results.GetResult();
IEnumerable categories=results.GetResult();
在上面的存储过程中,我们有两个select查询 1.选择“无联接查询” 2.选择带有联接的查询

但在上面的第二个select查询中,显示的数据来自其中一个表,即“来自类别”表。但我们使用了join,希望显示数据表,其中包含来自两个表的结果,即来自类别和后类别的结果

  • 如果有人能让我知道如何使用LINQtoSQL实现这一点,请告诉我
  • 如果使用上述方法与使用简单SQL实现上述方法相比,性能权衡是什么
  • (在微软负责.Net开发团队的那个家伙)几个月前在他的博客上讲述了如何做到这一点,比我以往任何时候都要好,。在该页面上有一个标题为“处理存储过程中的多个结果形状”的部分。这说明了如何处理来自不同形状(或相同形状)的存储过程的多个结果


    我强烈建议订阅他的RSS提要。他几乎是万有网上的权威来源。

    嘿,伙计,这有用吗

    IEnumerable<Post> posts;
    IEnumerable<Category> categories;
    
    using (BlogContext ctx = new BlogContext(...))
    {
        ctx.DeferredLoadingEnabled = false; // THIS IS IMPORTANT.
        IMultipleResults results = ctx.GetPostByID(...);
        posts = results.GetResult<Post>().ToList();
        categories = results.GetResult<Category>().ToList();
    }
    // Now we need to associate each category to the post.
    // ASSUMPTION: Each post has only one category (1-1 mapping).
    if (posts != null)
    {
        foreach(var post in posts)
        {
            int postId = post.PostId;
            post.Category = categories
                .Where(p => p.PostId == postId)
                .SingleOrDefault();
        }
    }
    
    IEnumberposts;
    可数范畴;
    使用(BlogContext ctx=newblogcontext(…)
    {
    ctx.DeferredLoadingEnabled=false;//这很重要。
    IMultipleResults=ctx.GetPostByID(…);
    posts=results.GetResult().ToList();
    categories=results.GetResult().ToList();
    }
    //现在我们需要将每个类别与帖子关联起来。
    //假设:每个帖子只有一个类别(1-1映射)。
    if(posts!=null)
    {
    foreach(var post in post)
    {
    int postId=post.postId;
    post.Category=类别
    .其中(p=>p.PostId==PostId)
    .SingleOrDefault();
    }
    }
    
    嗯。让我们把它分解一下

    首先,在using块中有一个很好的连接(因此它被很好地处理)

    接下来,我们确保延迟加载处于关闭状态。否则,当您尝试进行设置(例如,
    post.Category==blah
    )时,它将看到它是空的,延迟加载数据(例如,对数据库进行一次修改)设置数据,然后覆盖刚刚从数据库中拖拽下来的内容,结果是那里
    Where(…)
    方法。呸!小结:确保查询范围的延迟加载已关闭

    最后,对于每个帖子,迭代并设置第二个列表中的类别

    这有用吗

    编辑
    通过调用
    ToList()
    方法修复了它,这样它就不会抛出枚举错误。

    只是好奇,如果一篇文章有一个或多个类别,是否可以不使用for循环,而是使用连接一次加载Post.PostCategories和类别列表(一对多)

    var rslt = from p in results.GetResult<Post>()
               join c in results.GetResult<Category>() on p.PostId = c.PostID
               ...
               p.Categories.Add(c)
    
    var rslt=来自results.GetResult()中的p
    在p.PostId=c.PostId上的results.GetResult()中加入c
    ...
    p、 类别.添加(c)
    
    我在上讨论了一些类似的问题,以防您想参考。纯。克洛姆在这方面很有知识,也许值得看看他的答案。。。该博客似乎描述了一个可能是不同形状的结果集,但不是多个结果集