1

好的,所以我再次测试 EF 的性能,我只想从我的数据库中返回一个简单的结果。

例子

var jobsList = from j in mf.Jobs
                       where j.UserID == 1001 select new { Job = j };

不幸的是,这将我的用户对象加入了这个列表,我不希望 EF 这样做。我如何告诉EF不要仅仅因为有关系而加入。基本上我只想要该表中的一个简单行。

还是我需要使用不同类型的检索。我仍在使用下面的基本类型的数据库检索,我觉得现在有更好的方法来处理数据库工作。

SqlConnection myconnection = new SqlConnection();

编辑

基本上我在更清晰的背景下说的话。是不是只得到以下内容。

Job.JobID
Job.UserID
//Extra properties

我得到

Job.JobID
Job.UserID
Job.User
//Extra properties

该用户对象很容易消耗比需要更多的内存,而且我不需要它。

我的解决方案

所以我仍然不太相信EF,这就是原因。我关闭了 LazyLoading 并将其打开,并没有真正注意到那里的性能差异太大。然后,我将我的 SqlConnection 类型方法使用的数据量与我的 EF 方法进行了比较。

我得到了完全相同的结果集,这是性能差异。

对于我的实体框架方法,我会返回一份工作列表。

MyDataEntities mf = new MyDataEntities(); // 4MB for the connection...really?
mf.ContextOptions.LazyLoadingEnabled = false;
// 9MB for the list below
var test = from j in mf.Jobs
           where j.UserID == 1031
           select j;
foreach (Job job in test) {
     Console.WriteLine(job.JobID);
}

对于执行存储过程并返回结果集的我的 SqlConnection 方法。

//356 KB for the connection and the EXACT same list.
List<MyCustomDataSource.Jobs> myJobs = MyCustomDataSource.Jobs.GetJobs(1031); 

我完全理解 Entity Framework 比标准的 SqlConnection 做得更多,但是如果它要为结果集占用至少 25 倍的内存,为什么还要大肆宣传。只是似乎不值得。

毕竟,我的解决方案是不使用 EF。

4

5 回答 5

1

User属性是作业类的一部分,但在您访问它之前不会被加载(延迟加载)。所以它实际上并没有“加入”。

如果您只想要两个指定的列,您可以编写

var jobsList = from j in mf.Jobs
               where j.UserID == 1001 
               select new { 
                          Job.JobID, 
                          Job.UserID 
                          };
于 2012-05-08T22:09:38.583 回答
1

此行为最可能的原因是您将LazyLoadingEnabled属性设置为 true。

如果是这种情况,则不会在原始查询中恢复用户。但是,如果您尝试访问此属性,即使您在调试时通过检查进行访问,它也会从数据库中加载。但前提是您尝试访问它。

您可以检查这个打开一个 SQL Server Profiler,并查看哪些命令开始发送到数据库。

您的代码没有使用急切加载或显式加载。所以这一定是原因。

于 2012-05-08T22:11:50.733 回答
0

实体框架支持延迟加载属性。但是,它具有表格拆分功能

强调属性。当然,Entity Framework 支持延迟加载行

于 2012-05-08T22:34:10.347 回答
0

在您访问 Job 的 User 属性之前,用户实际上并未附加到上下文。如果您想为用户获取空值,请关闭延迟加载。

于 2012-05-08T22:17:27.390 回答
0

我认为 EF 不知道您只想要一个结果。尝试这样的事情。

Job jobsItem = mf.Jobs.Single(j=>j.UserID==1001)

如果你不想使用lambas...

Job JobItem = (from j in mf.Jobs where j.UserID == 1001 select j).Single()

我现在附近没有编译器,我希望语法是正确的。如果您愿意,可以使用var代替Job您的变量。它没有效果,但我认为Job在这种情况下更具可读性。

于 2012-05-08T21:57:02.110 回答