1

我有 2 张桌子

表A:

TableAID int,
Col1 varchar(8)

表B:

TableBID int
Col1 char(8),
Col2 varchar(40)

当我在 2 个表上运行 SQL 查询时,它返回以下行数

SELECT * FROM tableA (7200 rows)
select * FROM tableB (28030 rows)

在 col1 上加入并选择数据时,它返回以下行数

select DISTINCT a.Col1,b.Col2 FROM tableA a
join tableB b on a.Col1=b.Col1 (6578 rows)

以上 2 个表在不同的数据库上,所以我创建了 2 个 EF 模型并分别重试数据,并尝试使用具有以下功能的 linq 将它们加入代码中。令人惊讶的是,它返回 2886 条记录而不是 6578 条记录。难道我做错了什么?各个列表似乎返回了正确的数据,但是当我加入它们时,SQL 查询和 linq 查询的记录数不同。

非常感谢您对此的任何帮助。

// This function is returning 2886 records      
public List<tableC_POCO_Object> Get_TableC() 
{
    IEnumerable<tableC_POCO_Object> result = null;
    List<TableA> tableA_POCO_Object = Get_TableA(); // Returns 7200 records
    List<TableB> tableB_POCO_Object = Get_TableB(); // Returns 28030 records
    result = from tbla in tableA_POCO_Object
         join tblb in tableB_POCO_Object on tbla.Col1 equals tblb.Col1
         select new tableC_POCO_Object 
         {
         Col1 = tblb.Col1,
         Col2 = tbla.Col2
         };
    return result.Distinct().ToList();
}
4

3 回答 3

2

问题在于,在您的 POCO 世界中,您正在尝试使用直接比较来比较两个字符串(这意味着它区分大小写)。这可能适用于 SQL 世界(当然,除非您启用了区分大小写),但是当您拥有"stringA" == "StringA". 您应该做的是将连接列规范化为全部大写或小写:

join tblb in tableB_POCO_Object on tbla.Col1.ToUpper() equals tblb.Col1.ToUpper()

连接运算符使用指定的键(从第二个集合开始)创建一个查找,并通过检查生成的查找将原始表/集合连接回来,因此如果哈希值不同,它们将不会连接。

要点是,除非您标准化为相同的 cAsE,否则在字符串数据/属性上加入 OBJECT 集合是不好的。对于某些 DB 提供程序的 LINQ,如果数据库不区分大小写,那么这无关紧要,但在 CLR/L2O 世界中始终很重要。

编辑:啊,没有意识到它是CHAR(8)代替VARCHAR(8),这意味着无论如何它都会填充到 8 个字符。在这种情况下,tblb.Col1.Trim()将解决您的问题。但是,在处理 LINQ to Objects 查询时仍要记住这一点。

于 2012-05-29T19:29:44.153 回答
0

正如 SPFiredrake 正确指出的那样,这可能是由区分大小写引起的,但我还必须问你为什么以这种方式编写代码,为什么不这样:

// This function is returning 2886 records      
public List<tableC_POCO_Object> Get_TableC() 
{
    return from tbla in Get_TableA()
           join tblb in Get_TableB() on tbla.Col1 equals tblb.Col1
           select new tableC_POCO_Object 
           {
             Col1 = tblb.Col1,
             Col2 = tbla.Col2
           }.Distinct().ToList();
}

其中 Get_TableA() 和 Get_TableB() 返回 IEnumerable 而不是 List。您必须注意这一点,因为当您转换为列表时,查询将立即执行。您想向数据库服务器发送单个查询。

于 2012-05-29T20:23:02.060 回答
0

这可能是因为您比较 aVARCHAR和 aCHAR列。在 SQL 中,这取决于ANSI_PADDINGsql server 上的设置,而在 C# 中,使用 DataReader 读取字符串值并使用标准字符串函数进行比较。

试试tblb.Col1.Trim()你的 LINQ 语句。

于 2012-05-29T19:35:31.147 回答