Sql 在Linq查询中结合join和String.Contains

Sql 在Linq查询中结合join和String.Contains,sql,linq,string,join,contains,Sql,Linq,String,Join,Contains,我使用以下linq查询在两个表之间创建左连接: var joinResultRows = from leftTable in dataSet.Tables[leftTableName].AsEnumerable() join rightTable in dataSet.Tables[rightTableName].AsEnumerable()

我使用以下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 };
var joinResultRows=来自dataSet.Tables[leftTableName].AsEnumerable()中的leftTable
参加
dataSet.Tables[rightTableName].AsEnumerable()中的rightTable
在leftTable.Field(leftComparedColumnName)上等于rightTable.Field(rightComparedColumnName)
进入左联合结果
选择new{leftTable,leftJoinedResult};
我想得到回答这个问题的行: 左列中的字符串值包含右列中的字符串值

我试过这个:

            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 };
var joinResultRows=来自dataSet.Tables[leftTableName].AsEnumerable()中的leftTable
参加
dataSet.Tables[rightTableName].AsEnumerable()中的rightTable
在leftTable.Field(leftComparedColumnName).Contains(rightTable.Field(rightComparedColumnName))上等于true
进入左联合结果
选择new{leftTable,leftJoinedResult};
但它不起作用,因为在联接的左侧无法识别rightTable


如何创建一个结果为String.Contains的联接,我是在where子句中还是在On子句中执行Contains操作?

您尝试过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 };
var结果=
从dataSet.Tables[leftTableName].AsEnumerable()中的左侧开始
从dataSet.Tables[rightTableName].AsEnumerable()中的右侧开始
其中left.Field(leftComparedColumnName).Contains(right.Field(rightComparedColumnName))
选择新{左,右};
编辑:

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

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());
类包含SequalityComparer:IEqualityComparer
{
public bool Equals(string right,string left){return left.Contains(right);}
public int GetHashCode(字符串obj){return 0;}
}
var结果=
dataSet.Tables[leftTableName].AsEnumerable().GroupJoin(
dataSet.Tables[rightTableName].AsEnumerable(),
左=>左,
右=>右,
(left,leftJoinedResult)=>new{left=left,leftJoinedResult=leftJoinedResult},
新ContainesQualityComparer());
键比较通过自定义IEqualityComparer运行。只有当left和right的GetHashCode()相同,并且Equals返回true时,才会连接两行


希望能有所帮助。

我通过创建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 };
var joinResultRows=来自dataSet.Tables[leftTableName].AsEnumerable()中的leftDataRow
来自dataSet.Tables[rightTableName].AsEnumerable()中的rightDataRow
.其中(右行=>
{
//不要在Contains中包含“”字符串,因为“”始终被包含
//在任何字符串中。
if(String.IsNullOrEmpty(rightRow.Field(rightComparedColumnName)))
返回false;
返回leftDataRow.Field(leftComparedColumnName).Contains(rightRow.Field(rightComparedColumnName));
}).DefaultIfEmpty()//使右表的行或匹配行为空
选择new{leftDataRow,rightDataRow};

谢谢你的提示:)

+1 for SelectMany-LINQ只支持通过键相等对序列中的元素进行“相等联接”。SelectMany是我没有想到的,谢谢。它确实找到了匹配项,但并没有解决我的问题,因为我需要一个左连接来创建一个新的连接表,或者至少是一个匿名类型,它有两个表——左连接表和连接表(如上面的示例所示)。执行上述查询后,我使用leftTable和leftJoinedResult手动构建了结果表。我可以让SelectMany left加入吗?我相信没有真正的方法来实现您正在尝试的LinQ和匿名类型。但是有很多解决方法,我会在上面的帖子中为你解决。我已经深入研究了一下,我用一个GroupJoin重载IEqualityComparer复制了想要的效果。