C# Lambda查询转换。按选择行计数(EF6代码优先)
我有两张简单的桌子 波斯特是大师,拥有n张选票。我想返回他们的选票计数职位。 这是我的代码:C# Lambda查询转换。按选择行计数(EF6代码优先),c#,sql-server,performance,entity-framework,entity-framework-6,C#,Sql Server,Performance,Entity Framework,Entity Framework 6,我有两张简单的桌子 波斯特是大师,拥有n张选票。我想返回他们的选票计数职位。 这是我的代码: db.posts.Select(p=> new PostlDto{Title= p.Title, VoteCount= p.Votes.Count}) 我可以打一个电话来获取帖子,打几个电话来获取计数。 但问题是每次它都选择行,而不是对行进行计数,这是一个耗时的操作。 这就是sql分析器向我展示的内容 exec sp_executesql N'SELECT [Extent1].[Id]
db.posts.Select(p=>
new PostlDto{Title= p.Title, VoteCount= p.Votes.Count})
我可以打一个电话来获取帖子,打几个电话来获取计数。
但问题是每次它都选择行,而不是对行进行计数,这是一个耗时的操作。
这就是sql分析器向我展示的内容
exec sp_executesql N'SELECT
[Extent1].[Id] AS [Id],
[Extent1].[PostId] AS [PostId],
FROM [dbo].[Votes] AS [Extent1]
WHERE [Extent1].[PostId] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=6
我还尝试通过在基本查询中包含投票表来执行count 1调用,但也花费了太长时间,因为它还返回行而不是count|
db.posts
.Include(p=>p.Votes)
.Select(p=>
new PostlDto{Title= p.Title, VoteCount= p.Votes.Count})
这就是它转换为的查询
SELECT
[Project1].[Id] AS [Id],
[Project1].[Title] AS [Title],
[Project1].[C1] AS [C1],
[Project1].[Id1] AS [Id1],
[Project1].[Pid] AS [Pid],
[Project1].[PostId] AS [PostId],
FROM ( SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Title] AS [Title],
[Extent2].[Id] AS [Id1],
[Extent2].[PostId] AS [PostId],
CASE WHEN ([Extent2].[Id] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1]
FROM [dbo].[Posts] AS [Extent1]
LEFT OUTER JOIN [dbo].[Votes] AS [Extent2] ON [Extent1].[Id] = [Extent2].[PostId]
) AS [Project1]
ORDER BY [Project1].[Id] ASC, [Project1].[C1] ASC
如何将其改为运行简单计数|
运行这些查询需要几秒钟 一定还有别的事。将您的代码与此非复制代码进行比较:
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Data;
using System.Diagnostics;
namespace Ef6Test
{
public class Post
{
public int Id { get; set; }
public string Title { get; set; }
public virtual ICollection<Vote> Votes { get; } = new HashSet<Vote>();
}
public class Vote
{
public int Id { get; set; }
public Post Post { get; set; }
}
public class PostDto
{
public string Title { get; set; }
public int VoteCount { get; set; }
}
class Db : DbContext
{
public DbSet<Post> Posts { get; set; }
public DbSet<Vote> Votes { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseAlways<Db>());
using (var db = new Db())
{
db.Database.Log = m => Console.WriteLine(m);
db.Database.Initialize(false);
var posts = db.Posts.Select(p => new PostDto { Title = p.Title, VoteCount = p.Votes.Count }).ToList();
}
Console.WriteLine("Hit any key to exit");
Console.ReadKey();
}
}
}
这个问题很愚蠢!我有一个方法,我用它将我的对象转换成DTO,比如.select(convert),这是一个非常简单的方法。这就是EF变傻的原因!:\请不要把问题的答案加上去。@CodyGray,好的,那么把它放在哪里呢?大卫已经回答了。你已经在大卫的回答下发表了评论。您可以建议进行编辑,以使实际解决方案更加清晰。为了使编辑获得批准,您需要编写一份非常清晰的编辑摘要。@CodyGray ok,Cool:)
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[Title] AS [Title],
(SELECT
COUNT(1) AS [A1]
FROM [dbo].[Votes] AS [Extent2]
WHERE [Extent1].[Id] = [Extent2].[Post_Id]) AS [C1]
FROM [dbo].[Posts] AS [Extent1]