在Linq查询中将join与String.Contains结合起来

时间:2009-09-01 13:51:12

标签: sql linq string join contains

我有以下linq查询,它在两个表之间创建左连接:

            var joinResultRows = from leftTable in dataSet.Tables[leftTableName].AsEnumerable()
                             join
                                  rightTable in dataSet.Tables[rightTableName].AsEnumerable()
                                    on leftTable.Field<string>(leftComparedColumnName) equals rightTable.Field<string>(rightComparedColumnName)
                                        into leftJoinedResult
                             select new { leftTable, leftJoinedResult };

我想获得回答此问题的行: 左列中的String值包含右列中的字符串值。

我试过这个:

            var joinResultRows = from leftTable in dataSet.Tables[leftTableName].AsEnumerable()
                             join
                                  rightTable in dataSet.Tables[rightTableName].AsEnumerable()
                                    on leftTable.Field<string>(leftComparedColumnName).Contains(rightTable.Field<string>(rightComparedColumnName)) equals true
                                        into leftJoinedResult
                             select new { leftTable, leftJoinedResult };

但它不起作用,因为在连接的左侧无法识别rightTable。

如何创建一个产生String.Contains的连接,我在'where'子句或'On'子句中执行包含吗?

2 个答案:

答案 0 :(得分:5)

您是否尝试过SelectMany?

var result =
 from left in dataSet.Tables[leftTableName].AsEnumerable()
 from right in dataSet.Tables[rightTableName].AsEnumerable()
 where left.Field<string>(leftComparedColumnName).Contains(right.Field<string>(rightComparedColumnName))
 select new { left, right };

编辑:

以下内容应具有预期效果:

class ContainsEqualityComparer: IEqualityComparer<string>
{
    public bool Equals(string right, string left) { return left.Contains(right); }
    public int GetHashCode(string obj) { return 0; }
}

var result =
    dataSet.Tables[leftTableName].AsEnumerable().GroupJoin(
        dataSet.Tables[rightTableName].AsEnumerable(),
        left => left,
        right => right,
        (left, leftJoinedResult) => new { left = left, leftJoinedResult = leftJoinedResult },
        new ContainsEqualityComparer());

密钥比较通过自定义IEqualityComparer运行。只有当左边和右边的GetHashCode()相同时才会连接两行,而Equals返回true。

希望它有所帮助。

答案 1 :(得分:3)

我通过创建SelectMany(join)来解决它,左表包含所有记录,如果没有匹配则右边保持null:

var joinResultRows = from leftDataRow in dataSet.Tables[leftTableName].AsEnumerable()
                             from rightDataRow in dataSet.Tables[rightTableName].AsEnumerable()
                             .Where(rightRow => 
                                 {
                                     // Dont include "" string in the Contains, because "" is always contained
                                     // in any string.                                         
                                     if ( String.IsNullOrEmpty(rightRow.Field<string>(rightComparedColumnName)))
                                         return false;

                                     return leftDataRow.Field<string>(leftComparedColumnName).Contains(rightRow.Field<string>(rightComparedColumnName));

                                 }).DefaultIfEmpty() // Makes the right table nulls row or the match row
                              select new { leftDataRow, rightDataRow };

感谢您提示:)