Linq to sql 具有多个结果的Linq到SQL存储过程
我们遵循下面的方法,使用LINQ to 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
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,希望显示数据表,其中包含来自两个表的结果,即来自类别和后类别的结果
我强烈建议订阅他的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)
我在上讨论了一些类似的问题,以防您想参考。纯。克洛姆在这方面很有知识,也许值得看看他的答案。。。该博客似乎描述了一个可能是不同形状的结果集,但不是多个结果集