为什么Entity Framework尝试SELECT所有列,即使我只指定了两个?

Equ*_*lsk 12 c# sql-server asp.net-mvc entity-framework

我继承了一个ASP MVC项目,该项目使用Entity Framework 6.1.3与Dynamics CRM 2011 SQL数据库进行交互.

我正在使用此查询尝试获取所有具有帐号的活动帐户,并且我只选择两列为匿名类型:

var results = context.Accounts
              .Where(a => (a.AccountNumber != null) 
                       && (a.StateCode == (int)AccountState.Active))
              .Select(a => new 
              { 
                  a.AccountId, 
                  a.AccountNumber 
              });
Run Code Online (Sandbox Code Playgroud)

(contextDbContext,Accounts是,是DbSet<Account>,Account已定义所有字段,包括自项目创建以来删除的字段.这些字段由EF生成.)

执行查询时,我得到以下异常:

列名称"Opportunity_1","Opportunity_2",...,"Opportunity_7"无效

提到的所有列都是自创建此项目以来已从数据库中删除的列.

发生此错误是因为EF运行的SQL查询实际上如下所示:

SELECT     
    [Extent1].[StateCode] AS [StateCode],     
    [Extent1].[AccountId] AS [AccountId],     
    [Extent1].[AccountNumber] AS [AccountNumber]   

FROM (SELECT     
        [Account].[AccountId] AS [AccountId],     
        [Account].[AccountNumber] AS [AccountNumber],     
        ...
        !! EVERY SINGLE COLUMN !!
        ...
        [Account].[Opportunity_1] AS [Opportunity_1], // These have been deleted
        [Account].[Opportunity_2] AS [Opportunity_2]  // from the database

      FROM [dbo].[Account] AS [Account]) AS [Extent1] 

 WHERE ([Extent1].[AccountNumber] IS NOT NULL) AND (0 = [Extent1].[StateCode])
Run Code Online (Sandbox Code Playgroud)

我没想到它会尝试选择每一列,显然因为字段已从数据库中删除而不是模型我得到错误.

我已经阅读了几篇帖子,表明我的查询看起来是正确的,它应该只选择3个必需的列并忽略其余的: 一个/两个/三个

我想避免重新生成整个架构/模型/数据库中的任何内容,或者每次我对数据库进行更改时都会发现自己这样做.

是否可以从数据库中仅选择这两列并忽略所有其他列,或者这就是EF的工作方式,我将更新模型并每次重新部署项目?


这是整个DbContext模型:

namespace AccountMarker.Models
{
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;

    public partial class CRMEntities : DbContext
    {
        public CRMEntities()
            : base("name=CRMEntities")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }

        public virtual DbSet<Account> Accounts { get; set; }
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 2

当您创建实体并删除之前映射的特定列时,EF 将获取相同的引用,并尝试根据实体而不是您所做的查询来查找列。

快速解决方案,删除表构建项目的实体并将其再次添加到 emdx 模型中并重新构建。

或者从已删除的 dbcontext 中删除所有列。