好的,所以我再次测试EF的性能,我只想从我的数据库中获得一个简单的结果。
实施例
var jobsList = from j in mf.Jobs
where j.UserID == 1001 select new { Job = j };
这很遗憾地将我的User对象加入到这个列表中,我不希望EF这样做。如何告诉EF不要因为存在关系而加入。基本上我只想从该表中获得一个简单的行。
或者我是否需要使用不同类型的检索。我仍在使用下面的基本类型的数据库检索,我觉得现在有更好的方法来处理数据库工作。
SqlConnection myconnection = new SqlConnection();
修改
基本上我在更清晰的背景下说的是什么。是不是只得到以下内容。
Job.JobID
Job.UserID
//Extra properties
我得到了
Job.JobID
Job.UserID
Job.User
//Extra properties
用户对象很容易消耗比所需更多的内存,而且我不需要它。
我的解决方案
所以我仍然不太相信EF,这就是原因。我关闭了LazyLoading并打开它,并没有真正注意到那里的性能差异太大。然后,我比较了我的SqlConnection类型方法使用的数据量与EF方法的比较。
我得到完全相同的结果集,这里是性能差异。
对于我的Entity Framework方法,我会找回一份工作列表。
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);
我完全理解实体框架的方式不仅仅是标准的SqlConnection,而是为什么所有这些炒作如果它将为结果集至少增加25倍的内存。只是看起来不值得。
我的解决方案毕竟不是EF。
答案 0 :(得分:1)
User
属性是作业类的一部分,但在访问它之前不会加载(延迟加载)。所以它实际上并没有“加入”。
如果您只想要两个指定的列,则可以编写
var jobsList = from j in mf.Jobs
where j.UserID == 1001
select new {
Job.JobID,
Job.UserID
};
答案 1 :(得分:1)
此行为最可能的原因是您将LazyLoadingEnabled
property设置为true。
如果是这种情况,则不会在原始查询中恢复用户。但是,如果您尝试访问此属性,即使您在调试时通过检查执行此操作,也将从数据库加载。但只有当你试图访问它时才会这样。
您可以检查此打开SQL Server Profiler,并查看开始发送到数据库的命令。
您的代码未使用预先加载或显式加载。所以这一定是原因。
答案 2 :(得分: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
。它没有效果,但我认为{{1}}在这种情况下更具可读性。
答案 3 :(得分:0)
在访问Job的User属性之前,用户实际上没有附加到上下文。如果要为User获取null,请关闭延迟加载。
答案 4 :(得分:0)
实体框架does not支持lazy loading of properties。但是,它有table-splitting
强调属性。当然,Entity Framework支持延迟加载行