为啥对 List<T> 的迭代没有从 SQL 视图中给我正确的值? [复制]

Posted

技术标签:

【中文标题】为啥对 List<T> 的迭代没有从 SQL 视图中给我正确的值? [复制]【英文标题】:Why is this iteration over a List<T> not giving me the correct values out of the SQL view? [duplicate]为什么对 List<T> 的迭代没有从 SQL 视图中给我正确的值? [复制] 【发布时间】:2021-03-13 22:33:26 【问题描述】:

我正在开发一个必须在数据网格中显示表格的新应用程序。数据网格的列由我的一位同事编写的 SQL 视图检索。但是,返回的数据看起来像是重复数据,例如如果 SQL 查询格式不正确,您会得到这样的数据。下面是定义 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'

但是,数据网格显示数据如下:

因此,我决定通过创建一个控制台应用程序来简化事情,只从视图中提取数据并迭代返回的内容。我首先在现有数据库中使用了 EF 的代码。这是控制台应用程序的代码:

class Program

    static void Main(string[] args)
    
        using (var ctx = new CodeModel())
        
            var bozo = ctx.vwDataDictionaries.ToList();
            int i = 0;
            foreach (var item in bozo)
            
                i++;
                Console.WriteLine($"i: i, ID: item.ID, TABLE_NAME: item.TABLE_NAME, COLUMN_NAME: item.COLUMN_NAME");
            
        
        Console.WriteLine("Finished");
    

但如果我运行那个控制台应用程序,我会得到如下值:

在 C# 应用程序中运行查询会返回 282 条记录。都有一个列名“ID”。但是,如果我在 Azure Data Studio 中运行相同的查询,我会得到以下信息:

当然,我知道我没有进行排序或过滤,但我仍然不明白为什么示例程序会返回如此多的 COLUMN_NAME 重复项。

我正在使用 VS 2019 版本 16.8.2。 .NET Framework 4.5.2 和 EF 6。

【问题讨论】:

您是否针对相同的数据源运行此视图?在 SQL Server 数据库中,[TABLE_CATALOG] 按照this answer 存储数据库的名称。 是的,我正在针对用于 EF 的同一数据源运行视图。 感谢您,感谢留下指向解决此问题的其他帖子的链接的人。它帮助了我。 【参考方案1】:

我不确定您到底期待什么,但列可以有多个约束。看起来您正在获取整个架构中所有列的列表,而不是单个表的列。

如果您查看查询中的三个表中的每一个;

select * from [INFORMATION_SCHEMA].[COLUMNS] order by table_schema, TABLE_NAME
select * from [INFORMATION_SCHEMA].[CONSTRAINT_COLUMN_USAGE] order by table_schema, TABLE_NAME
select * from [INFORMATION_SCHEMA].[TABLE_CONSTRAINTS] order by table_schema, TABLE_NAME

您可能会更好地了解与您的期望不同的地方。

【讨论】:

我的一位同事写了这个视图。他编写它的目的是过滤 TABLE_NAME 视图返回的内容。

以上是关于为啥对 List<T> 的迭代没有从 SQL 视图中给我正确的值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥 C# 数组对 Enumeration 使用引用类型,而 List<T> 使用可变结构?

为啥 WCF 会返回 myObject[] 而不是 List<T> 像我期望的那样?

如何迭代子类中的 List<T> 基类?

为啥我在 List<List<T>> 中复制 List<T> 时存在依赖关系? [复制]

为啥 List<T> 在 .NET 4.5 中实现 IReadOnlyList<T>?

为啥 List<T>.ForEach 允许修改其列表?