SQL到LINQ实体的SQL查询配置文件不需要
本文关键字:SQL 配置文件 不需要 查询 实体 LINQ | 更新日期: 2023-09-27 18:17:09
所以我有这个查询:
using (var unitOfWork = this.unitOfWorkFactory.Create(LockType.Read))
{
var blogRepository = this.repositoryFactory.Create<SpaTest.Domain.Blogging.Blog>(unitOfWork);
var postRepository = this.repositoryFactory.Create<SpaTest.Domain.Blogging.Post>(unitOfWork);
var blogs = blogRepository.Retrieve()
.GroupJoin(
postRepository.Retrieve(),
b => b.Id,
p => p.BlogId,
(blog, posts) =>
new Models.Blogging.Blog()
{
Title = blog.Title,
Content = blog.Content,
DateAdded = blog.DateAdded,
Id = blog.Id,
PostCount = posts.Count()
}).Distinct();
var result = blogs.ToArray();
return this.Ok(result);
}
我希望得到一个连接语句,因为MSDN声明这相当于一个左外连接。
基本上,我想要返回所有的博客和每个博客的帖子数。SQL Profiler实际上显示了2个单独的select语句:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Content] AS [Content],
[Extent1].[BlogId] AS [BlogId],
[Extent1].[UserId] AS [UserId],
[Extent1].[DateAdded] AS [DateAdded]
FROM [dbo].[Posts] AS [Extent1]
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Title] AS [Title],
[Extent1].[Content] AS [Content],
[Extent1].[UserId] AS [UserId],
[Extent1].[DateAdded] AS [DateAdded]
FROM [dbo].[Blogs] AS [Extent1]
所以我不知道这是怎么回事。
编辑
Retrieve()
实现:
/// <summary>
/// Retrieves entities from the repository based on the query provided
/// </summary>
/// <param name="query">
/// The query to use when matching entities in the repository
/// </param>
/// <returns>
/// The <see cref="IEnumerable{T}"/> of entities retrieved from the repository
/// </returns>
public virtual IEnumerable<TEntity> Retrieve(Expression<Func<TEntity, bool>> query)
{
if (query == null)
{
throw new ArgumentNullException("query", "A query must be specified to use the overloaded Retrieve method. To retrieve all entities, use Retrieve()");
}
return this.unitOfWork.Context.CreateObjectSet<TEntity>().AsNoTracking().Where(query);
}
背景更新
因此,在将using(var unitOfWork....
更改为using(var context = new DefaultContext())
后,我得到了这个sql输出:
SELECT
1 AS [C1],
[Project1].[Title] AS [Title],
[Project1].[Content] AS [Content],
[Project1].[DateAdded] AS [DateAdded],
[Project1].[Id] AS [Id],
[Project1].[C1] AS [C2]
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Title] AS [Title],
[Extent1].[Content] AS [Content],
[Extent1].[DateAdded] AS [DateAdded],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[Posts] AS [Extent2]
WHERE [Extent1].[Id] = [Extent2].[BlogId]) AS [C1]
FROM [dbo].[Blogs] AS [Extent1]
) AS [Project1]
在您的Retrieve
方法中,您隐式地从IQueryable<T>
转换为IEnumerable<T>
,这相当于在您的查询上调用AsEnumerable。这样做的结果是您的GroupJoin
调用使用IEnumerable<T>
实现(在内存中运行),而不是IQueryable<T>
实现(在DB上运行)。
考虑到执行内存中GroupJoin
所需的唯一东西是记录本身,这解释了为什么只生成两个SELECT
语句。要强制在DB端执行GroupJoin
,您需要从Retrieve
方法返回IQueryable<T>
。