我有以下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'子句中执行包含吗?
答案 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 };
感谢您提示:)