C# Database.SqlQuery和EF 6.1之间的性能有什么区别吗?

C# Database.SqlQuery和EF 6.1之间的性能有什么区别吗?,c#,asp.net,asp.net-mvc,entity-framework,asp.net-web-api,C#,Asp.net,Asp.net Mvc,Entity Framework,Asp.net Web Api,我有两种不同的方法从SQL数据库获取数据: var sql = @"Select Exam.Name, Test.TestId, Test.QuestionsCount, Test.Title FROM Test INNER JOIN Exam ON ( Test.ExamId = Exam.ExamId) WHERE Test.TestStatusId = 1"; var te

我有两种不同的方法从SQL数据库获取数据:

var sql = @"Select Exam.Name, Test.TestId, Test.QuestionsCount, Test.Title
            FROM Test
            INNER JOIN Exam
               ON ( Test.ExamId = Exam.ExamId)
            WHERE Test.TestStatusId = 1";
        var tests1 = db.Database.SqlQuery<TestDTO>(sql).ToList();

        var tests2 = await db.Tests
            .Include(t => t.Exam)
            .Where(t => t.TestStatusId == 1)
            .Select(t => new TestDTO
            {
                ExamName = t.Exam.Name,
                Id = t.TestId,
                QuestionsCount = t.QuestionsCount,
                Title = t.Title
            })
            .ToListAsync();
var sql=@“选择Test.Name、Test.TestId、Test.QuestionsCount、Test.Title
从测试
内联考试
打开(Test.ExamId=Exam.ExamId)
其中Test.TestStatusId=1”;
var tests1=db.Database.SqlQuery(sql.ToList();
var tests2=等待数据库测试
.包括(t=>t.Exam)
.其中(t=>t.TestStatusId==1)
.选择(t=>newtestdto
{
ExamName=t.Exam.Name,
Id=t.TestId,
questionScont=t.questionScont,
Title=t.Title
})
.ToListAsync();

我意识到第二种方式似乎更“受欢迎”,但从性能的角度来看,这两种方式之间有什么区别吗。特别是第一种方法是否可以有一个异步版本,或者这样做的好处可能最小?

这两种检索数据的方法甚至不相等

在第二种方法中,您将编写一个LINQ到实体查询,并返回一个包含测试的测试列表。执行查询后,所有测试和检查都将添加到实体框架更改跟踪器中

在第一种方法中,您只是使用实体框架来执行一些SQL并将其转换为TestDTO对象。您的任何实体都不在更改跟踪器中


第一种方法可能会更快,因为您不涉及跟踪实体,但它们实际上不具有可比性,因为它们做的事情不同。您是否计划对测试和考试进行更改,并在DbContext上调用SaveChanges?如果是,那么您将使用第一种方法手动完成所有这些操作。我不知道你为什么要问这个问题,除非你在第二个查询中看到性能问题。如果您甚至不打算使用EF查询数据,为什么不在此时使用SqlReader或DataAdapter呢。

在每次迭代中使用秒表在循环中尝试1000次怎么样?取平均数,决定胜利者。对异步版本也要这样做……考虑到这一点,我鼓励您首先基于功能、可维护性和设计目标,然后基于性能做出决策。然后是在不需要更改跟踪的情况下提高EF性能。不需要更改跟踪。到目前为止,我认为第一种方法可能更易于维护。如有任何其他意见和建议,将不胜感激。我确实在构造函数中为其他内容设置了上下文。使用SqlReader或DataAdapter的优势是什么?谢天谢地,字符串查询的可维护性从来没有比linq查询更高——您可以使用linq进行编译时语法检查。另外,不要让EF DbContext的构造函数制造不相关的东西——DbContext应该是非常轻量级的,所以您可以经常(通过“使用”语句)创建和销毁它们