C# 使用LINQ在两个表之间选择不同的值
我有一个数据集,看起来像下面的信息 我试图用尽可能多的可用信息填充对象 所以我想从顶部数据集中获取UnitNum 65002,其余的从单列表中获取 我的代码:C# 使用LINQ在两个表之间选择不同的值,c#,linq,dataset,C#,Linq,Dataset,我有一个数据集,看起来像下面的信息 我试图用尽可能多的可用信息填充对象 所以我想从顶部数据集中获取UnitNum 65002,其余的从单列表中获取 我的代码: foreach (DataRow row in dsUnits.Tables[0].Rows) { var unit = new Unit.Unit { UnitNum = row["UnitNumber"].NullSafeToString(),
foreach (DataRow row in dsUnits.Tables[0].Rows)
{
var unit = new Unit.Unit
{
UnitNum = row["UnitNumber"].NullSafeToString(),
CustCode = row["CustCode"].NullSafeToString(),
Year = row["Year"].NullSafeToString(),
Make = row["Make"].NullSafeToString(),
Model = row["Model"].NullSafeToString()
};
UnitsInvolvedInBreakdown.Add(unit);
}
foreach (DataRow row in dsUnits.Tables[1].Rows)
{
if (UnitsInvolvedInBreakdown.Where(x => x.UnitNum == row["UnitNumber"].ToString()).Count() == 0)
{
var unit = new Unit.Unit
{
UnitNum = row["UnitNumber"].ToString()
};
UnitsInvolvedInBreakdown.Add(unit);
}
}
这对我来说效率很低,我尝试了下面的代码,但没有结果
var q = dsUnits.Tables[0].AsEnumerable().Except(dsUnits.Tables[1].AsEnumerable());
基本上,我的问题是,是否有一种方法可以使用linq从表0中选择UnitNumber,前提是表1中不存在UnitNumber
更好的解释
装置编号见表1。它可能在表0中
如果在表0中,我想从那里获取信息。我有更多信息
如果它不在表0中,我想从表1中获取信息,因为我必须获取我能获得的信息。但是我不想要复制品。如果我了解你的要求,这就是你要找的。它首先获取表1中的所有内容,然后通过Linq左外连接获取表2中不在表1中的所有内容:
var unitsFrom1 = dsUnits.Tables[0].AsEnumerable()
.Select(row => new Unit.Unit
{
UnitNum = row["UnitNumber"].NullSafeToString(),
CustCode = row["CustCode"].NullSafeToString(),
Year = row["Year"].NullSafeToString(),
Make = row["Make"].NullSafeToString(),
Model = row["Model"].NullSafeToString()
});
var unitsFrom2Notin1 =
from row in dsUnits.Tables[1].AsEnumerable()
join u1 in unitsFrom1
on row.Field<string>("UnitNumber") equals u1.UnitNum into outer
from outerJoin in outer.DefaultIfEmpty()
where outerJoin == null
select new Unit.Unit
{
UnitNum = row["UnitNumber"].NullSafeToString()
};
这是一个简单的循环,你需要从第一个循环中获取所有信息,从第二个循环中获取所有不在第一个循环中的信息。请注意,我使用:
var uniqueUnits = new HashSet<Unit.Unit>(new Unit.UnitComparer());
foreach (DataRow row in dsUnits.Tables[0].Rows)
{
Unit.Unit unit = new Unit.Unit
{
UnitNum = row["UnitNumber"].NullSafeToString(),
CustCode = row["CustCode"].NullSafeToString(),
Year = row["Year"].NullSafeToString(),
Make = row["Make"].NullSafeToString(),
Model = row["Model"].NullSafeToString()
};
uniqueUnits.Add(unit);
}
foreach (DataRow row in dsUnits.Tables[1].Rows)
{
Unit.Unit unit = new Unit.Unit
{
UnitNum = row["UnitNumber"].NullSafeToString()
};
uniqueUnits.Add(unit);
}
var uniqueUnits=newhashset(new Unit.UnitComparer());
foreach(数据行,单位为dsUnits.Tables[0]。行)
{
单位。单位=新单位。单位
{
UnitNum=行[“UnitNumber”]。NullSafeToString(),
CustCode=行[“CustCode”]。NullSafeToString(),
Year=行[“Year”]。NullSafeToString(),
Make=行[“Make”]。NullSafeToString(),
Model=行[“Model”]。NullSafeToString()
};
唯一单位。添加(单位);
}
foreach(数据行,单位为dsUnits.Tables[1]。行)
{
单位。单位=新单位。单位
{
UnitNum=行[“UnitNumber”]。NullSafeToString()
};
唯一单位。添加(单位);
}
如果由于数据集中已有数据而无法添加,则返回
false
。我发现,当我处于精神错乱的状态时,数据集往往会让我发疯。我发现通过类构建实体,然后使用linq查询实体更容易。由于时间不够,我复制了一个MSDN示例。你可以根据自己的需要修改它
var query =
from contact in contacts
from order in orders
where contact.ContactID == order.Contact.ContactID
&& order.TotalDue < totalDue
select new
{
ContactID = contact.ContactID,
LastName = contact.LastName,
FirstName = contact.FirstName,
OrderID = order.SalesOrderID,
Total = order.TotalDue
};
foreach (var smallOrder in query)
{
Console.WriteLine("Contact ID: {0} Name: {1}, {2} Order ID: {3} Total Due: ${4} ",
smallOrder.ContactID, smallOrder.LastName, smallOrder.FirstName,
smallOrder.OrderID, smallOrder.Total);
}
var查询=
从联系人中的联系人
从订单到订单
其中contact.ContactID==order.contact.ContactID
&&order.TotalDue
}这是实体框架吗?我喜欢。我在想有一种方法可以利用Intersect函数。非常感谢。我将运行一些单元测试,看看哪个执行得更快。@CalvinSmith:我不知道
Intersect
在这里有什么帮助。如果您在Unit.Unit
中重写了Equals
+GetHashCode
,则可以使用。您还可以将的重载与自定义的IEqualityComparer
一起使用。此外,它在concat中生成了重复的65002单位。我不认为仅仅在concat的末尾添加一个直接的distinct就可以解决这个问题,但我会试试看next@CalvinSmith:否,您不能使用Distinct
,因为默认情况下,这只会比较引用。并且两者都是具有相同单位编号的不同引用。这就是为什么我提到了Equals
+GetHashCode
。但我想知道为什么你会得到重复的。上面的第二个LINQ查询应该只从第二个表中获取尚未从第一个表中提取的行/单位。这就是为什么我使用了“外部连接”(来自outerJoin in in outer.DefaultIfEmpty(),其中outerJoin==null
)。@CalvinSmith:我展示了另一种使用自定义IEqualityComparer
)的方法。不清楚这如何有助于从表1中提取所有内容,以及从表2中提取所有缺失的内容,这是核心问题。这个样本是完全不相关的,不是吗?这并不能真正回答这个问题。我只是想提出一个建议,而不是过于傲慢地直接查询数据集。是的,该示例不相关,但提供了查询实体的linq构造。它没有涉及他的问题应该是什么样子。我要调查一下
var uniqueUnits = new HashSet<Unit.Unit>(new Unit.UnitComparer());
foreach (DataRow row in dsUnits.Tables[0].Rows)
{
Unit.Unit unit = new Unit.Unit
{
UnitNum = row["UnitNumber"].NullSafeToString(),
CustCode = row["CustCode"].NullSafeToString(),
Year = row["Year"].NullSafeToString(),
Make = row["Make"].NullSafeToString(),
Model = row["Model"].NullSafeToString()
};
uniqueUnits.Add(unit);
}
foreach (DataRow row in dsUnits.Tables[1].Rows)
{
Unit.Unit unit = new Unit.Unit
{
UnitNum = row["UnitNumber"].NullSafeToString()
};
uniqueUnits.Add(unit);
}
var query =
from contact in contacts
from order in orders
where contact.ContactID == order.Contact.ContactID
&& order.TotalDue < totalDue
select new
{
ContactID = contact.ContactID,
LastName = contact.LastName,
FirstName = contact.FirstName,
OrderID = order.SalesOrderID,
Total = order.TotalDue
};
foreach (var smallOrder in query)
{
Console.WriteLine("Contact ID: {0} Name: {1}, {2} Order ID: {3} Total Due: ${4} ",
smallOrder.ContactID, smallOrder.LastName, smallOrder.FirstName,
smallOrder.OrderID, smallOrder.Total);
}