【问题标题】:Problems understanding LINQ syntax. returned error理解 LINQ 语法的问题。返回错误
【发布时间】:2020-12-02 22:18:42
【问题描述】:

我正在开发一个接受文档作为上传文件的应用程序,这是一个具有多个值的 Excel 表格。它正在中断而不是上传...我已经找到了它正在中断的位置,但是我在理解这个确切的 LINQ 语法时遇到了问题。

    public static List<PoolManager> getPoolManagersLoadedinMaster()
    {
        using (HRCMSEntities context = new HRCMSEntities())
        {

            HRCompInfo compInfo = new HRCompInfo();
            DataTable dtCurrYear = compInfo.getConfiguration("CurrentYear");
            var currYear = Convert.ToInt32(dtCurrYear.Rows[0]["Config_Val"].ToString());

            var planningManagerQuery =
            from COMP_REC_ENC in context.COMP_REC_ENC.Where(m => m.Year == currYear)
            select new PoolManager
            {
                Planning_manager_ID = COMP_REC_ENC.Planning_Manager_ID
            };

            var planningManagerList = planningManagerQuery.Distinct().ToList();

            return planningManagerList;
        }
    }

此代码在尝试运行时会中断

PlanningMangerList = planningManagerQuery.Distinct().ToList() 

我检查了表格,数据在那里。有人可以帮我破译为什么这段代码会在那个确切的部分被破坏吗?理论会很好用......我收到了这个错误:

ERROR: System.Data.Entity.Core.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Invalid column name 'Special_6'. Invalid column name 'Special_9_New'. Invalid column name 'Special_10_New'. at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() at System.Data.SqlClient.SqlDataReader.get_MetaData() at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption, Boolean shouldCacheForAlwaysEncrypted) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior

我确实将这个项目从 SIT 数据库更改为 DEV 数据库...在实体框架方面,我确实更新了连接字符串目录,但不确定在实体框架方面连接字符串是否存在问题。我更新到这个了。

<add name="HRCMSEntities" connectionString="metadata=res://*/;provider=System.Data.SqlClient

谢谢

【问题讨论】:

  • 您能否添加一个 catch 子句并向我们展示 exception.ToString() 输出?
  • 是的,我现在正在这样做……一会儿
  • @noobprogrammer - 再看看。
  • @JeffreyPadgett - 我们可以看看 PoolManager 的类定义吗?
  • 如何启用 sql 查询的日志记录,然后尝试手动执行查询以查看问题所在

标签: c# asp.net linq


【解决方案1】:

您的错误原因与Distinct() 无关,也与ToList() 无关。这里报错,因为这是你定义的查询被执行的时刻。

我认为问题出在 Select 中,这对我来说有点奇怪。

您必须调试以确定问题出在 dbContext、Where 还是 Select

添加一些中间测试代码,每次执行查询。

var a = context.COMP_REC_ENC.ToList();
var b = context.COMP_REC_ENC
        .Where(m => m.Year == currYear)
        .ToList();
var c = context.COMP_REC_ENC
        .Where(m => m.Year == currYear)
        .Select(m => new PoolManager
        {
            Planning_manager_ID = COMP_REC_ENC.Planning_Manager_ID
        })
        .ToList();

换句话说:上下文有一系列项目,其名称为COMP_REC_ENC。此序列中的每个项目都有一个属性Year。仅保留序列中该属性的值等于 currYear 的那些 COMP_REC_ENC

首先:currYear 是一个 int。属性 Year 也是 int 吗?如果是这样,问题不在Where

接下来,从剩余的COMP_REC_ENC 对象序列中的每一项中,创建一个新的PoolManager。只有属性Planning_manager_ID 被填充。用于填充Planning_manager_ID 的值为COMP_REC_ENC.Planning_Manager_ID

奇怪的部分来了:我原以为您会使用当前COMP_REC_ENC 的属性之一来填充Planning_Manager_ID。我想你会在这里找到问题。

Planning_manager_ID = 

今后如何预防此类问题

我有几个建议给你:

  • 不要将 LINQ 方法语法与 LINQ 查询语法混用,来自 SQL 世界的人更喜欢查询语法。来自 C# 世界的人可能更喜欢方法语法。方法语法更灵活,因为很容易添加新的类似 LINQ 的方法。
  • 尽量给你的标识符起有意义的名字,这样每个读者都会立即知道它们代表什么。对相似项目的序列使用复数名词,对这些序列中的元素使用单数名词。
  • 不要认为通过使用短标识符来节省打字会更早完成您的项目。与其他人必须更改/测试/重用代码时理解代码所需的时间相比,节省的时间微不足道。

如果 dbContext 类已经被广泛使用,我可以理解很难说服您的项目负责人更改 dbContext。所以你必须坚持下去。

我不知道您的 dbSet COMP_REC_ENC 中存储了哪些项目,因此我将仅举一个示例来说明如果您遵守这些规则,您的查询将变得多么清晰

class ComputerPlanning
{
    public int Id {get; set; }                 // primary key
    ...

    public int Year {get; set;}   
    public int PlanningManagerId {get; set;}   // The foreign key to the planning manager
                                               // who created this planning
}

class PlanningDbContext : DbContext
{
    public DbSet<ComputerPlanning> ComputerPlannings {get; set;}
}
    

您根据指南的查询:

要求:从 ComputerPlannings 表中的所有计算机计划中,只保留 Year 等于 currentYear 的那些计算机计划。从每个剩余的 ComputerPlanning 中创建一个 PoolManager,其 PlanningManagerId 的值等于计算机规划 PlanningManagerId。删除重复项并将其全部放入列表中。

int currentYear = ...
List<PoolManager> poolManagers = planningContext.ComputerPlannings
    .Where(computerPlanning => computerPlanning.Year == currentYear)
    .Select(computerPlanning => new PoolManager
    {
         PlanningManagerId = computerPlanning.PlanningManagerId,
    })
    .Distinct()
    .ToList();

因为我坚持约定,所以阅读代码的每个人都可以很容易地看到代码按照要求执行。

顺便说一句,如果您在 Planning_manager_ID = ... 中出错,您的编译器可能已经发现了问题,而不是运行时。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多