【问题标题】:How do I make Entity Framework not join tables?如何使实体框架不连接表?
【发布时间】:2012-05-09 22:55:50
【问题描述】:

好的,所以我再次测试 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。

【问题讨论】:

  • 生成的SQL是什么样子的?
  • 是否启用了延迟加载?如果不是,则加入可能是因为您正在急切加载 User 属性。
  • “不幸的是,这会将我的用户对象加入此列表”是什么意思?
  • 为什么会有join? UserID 不只是Jobs 表中的一个外键列,SQL 对这个列有一个简单的 WHERE 子句吗?
  • @w.brian 我不确定什么是延迟加载。我会对此进行更多研究。

标签: c# sql entity-framework-4


【解决方案1】:

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

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

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

【讨论】:

  • 好吧,我想这就是我需要的。基本上,如果我想返回一个特定的类并且只返回那个类或者在这种情况下是表,我需要逐个字段地指定我想要的。
  • @meanbunny 如果您想从表作业中返回所有值,只需编写 ... select job 相关表将显示在对象上但不会被加载。
  • 啊啊啊我现在明白了。经过测试,这是完全合理的。 Ty 为您提供帮助。
【解决方案2】:

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

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

你可以打开一个 SQL Server Profiler 来检查这个,看看什么命令开始发送到数据库。

您的代码未使用预先加载或显式加载。所以一定是这个原因。

【讨论】:

    【解决方案3】:

    我认为 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 在这种情况下更具可读性。

    【讨论】:

    • 我认为这里的语法很完美。但是,请查看我的编辑并查看更多关于我所说的内容。很抱歉一开始的描述不完整。基本上我只想要用户 ID 而不是用户 ID 和用户。
    • 好的 :D 我已经阅读了您的编辑。然后我认为这都是关于延迟加载的概念。像 JotaBe 推荐你一样看看它。
    【解决方案4】:

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

    【讨论】:

      【解决方案5】:

      实体框架does not 支持lazy loading of properties。但是,它有table-splitting

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-01-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-30
        • 2021-08-26
        相关资源
        最近更新 更多