returns 的查询结果与 Entity Framework 查询的 COLUMN_NAME 的值相同,这没有意义

The result of a query returns the same value for COLUMN_NAME from an Entity Framework query, which doesn't make sense

几天来我一直在为这个问题苦苦挣扎。一位同事针对他也创建的 SQL 服务器视图编写了一个 LINQ 查询,returns 18 行用于他过滤的 table 名称。

他创建的视图使用的是系统视图INFORMATION_SCHEMA。奇怪的是,当 LINQ 查询 returns 结果时, COLUMN_NAME 的所有值都是 ID.

但是,当我运行一个SELECT反对同一个观点时,所有的COLUMN_NAMES都是不同的。我不明白为什么会有差异。

这是 SQL 服务器视图:

CREATE view [Core].[vwDataDictionary] 
AS
    SELECT 
        ROW_NUMBER() OVER(order by A.[TABLE_CATALOG]) AS [ID]   
        ,A.[TABLE_CATALOG]
        ,A.[TABLE_SCHEMA]
        ,A.[TABLE_NAME]
        ,A.[COLUMN_NAME]
        ,[ORDINAL_POSITION]
        ,[COLUMN_DEFAULT]
        ,[IS_NULLABLE]
        ,[DATA_TYPE]
        ,[CHARACTER_MAXIMUM_LENGTH]
        ,[CHARACTER_OCTET_LENGTH]
        ,[NUMERIC_PRECISION]
        ,[NUMERIC_PRECISION_RADIX]
        ,[NUMERIC_SCALE]
        ,[DATETIME_PRECISION]
        ,[CHARACTER_SET_CATALOG]
        ,[CHARACTER_SET_SCHEMA]
        ,[CHARACTER_SET_NAME]
        ,[COLLATION_CATALOG]
        ,[COLLATION_SCHEMA]
        ,[COLLATION_NAME]
        ,[DOMAIN_CATALOG]
        ,[DOMAIN_SCHEMA]
        ,[DOMAIN_NAME]
        ,B.[CONSTRAINT_NAME]
        ,C.[CONSTRAINT_TYPE]
    FROM 
        [INFORMATION_SCHEMA].[COLUMNS] AS A
    LEFT JOIN 
        [INFORMATION_SCHEMA].[CONSTRAINT_COLUMN_USAGE] AS B ON A.TABLE_NAME = B.TABLE_NAME 
                                                            AND A.COLUMN_NAME = B.COLUMN_NAME
    LEFT JOIN
        [INFORMATION_SCHEMA].[TABLE_CONSTRAINTS] AS C ON B.CONSTRAINT_NAME = C.CONSTRAINT_NAME
    WHERE 
        A.[TABLE_SCHEMA] = 'App'

他倾向于声明一个全局的 DbContext 来使用。我认为这是问题所在,所以我只是稍微更改了代码以使用本地 DbContext。不幸的是,它没有帮助,因为我所做的更改与他的代码所做的更改相同。

只有这一点不同,此 C# 代码的其余部分是他的:

using (var ctx = new CoreFrameworkEntities())
{
    var dd_fields_query = ctx.vwDataDictionaries.Where(d => d.TABLE_NAME == CurrentTableName);
    var dd_fields_query_list = dd_fields_query.ToList();

    foreach (var item in dd_fields_query_list)
    {
        string col_name = "";

        foreach (var camel in SplitCamelCase(item.COLUMN_NAME))
        {
            col_name = col_name + camel + " ";
        }

        col_name = col_name.Replace("_", "").Trim();

        if (item.COLUMN_NAME == "ID")
        {
            col_name = "ID";
        }
        else if (item.COLUMN_NAME == "InstrumentID")
        {
            col_name = "Instrument ID";
        }
        else if (item.COLUMN_NAME.EndsWith("ID"))
        {
            col_name = item.COLUMN_NAME.Split('I')[0] + " ID";
        }

        KeyValuePair<vwDataDictionary, string> kvp = new KeyValuePair<vwDataDictionary, string>(item, col_name);
        TableFields.Add(kvp);
    }
}

这是我写的 SELECT,用于将结果与 LINQ 查询的结果进行比较:

SELECT * 
FROM Core.vwDataDictionary
WHERE TABLE_NAME = 'Proficiency'

那么,为什么 LINQ 查询 returns 18 行,所有行的值为“ID”,而 SELECT returns 18 行都具有正确的列Proficiency table?

的名称

从 Entity Framework 使用时 views 有一个微妙的问题。

如果你有一个带 EF 的 table,你需要有一个 主键 来唯一标识每一行。通常,这是一个单独的列,例如ID 或类似的东西。

对于视图,您没有“主键”的概念 - 视图只包含一些 table 中的一些列。

因此,当 EF 映射视图时,它找不到主键 - 因此,它将使用视图中的所有不可为 null 的列 作为“替代”主键。

当 EF 现在读取数据时,它将获取所有列并创建一个代表该行的内存中对象。如果 EF 现在稍后从数据库 中读取另一行,其中构成视图的 替代 PK 的那些不可为空的列 是相同的 -然后它会想:“哎呀,我已经有了那一行”,只需将同一对象的另一个副本添加到您的结果集中即可。

所以在这种情况下,最终您可能会在 EF 结果集中有 18 个相同的行 - 即使 SQL 服务器输出正确显示不同数据。 ......

更新: 作为一个可能的解决方案,您可以尝试利用 sys.columnssys.tables 提供“更好”列的目录视图 - 非- 可为空的,每列不完全相同....

尝试这样的事情:

CREATE VIEW [Core].[vwDataDictionary] 
AS
    SELECT 
        t.Name,
        t.object_id,
        c.Name,
        c.column_id
        -- possibly later more columns here....
    FROM
        sys.tables t
    INNER JOIN
        sys.columns c ON c.object_id = t.object_id