早上好。我有一个列表“ changes” ,从中我从2个数据表中获取数据,因此数据表1中的“ Item” 等于数据表2中的“ ItemCode” ,如下所示。
var changes = (from dr1 in dtItemSicorax.AsEnumerable()
from dr2 in dtItemCloud.AsEnumerable()
where dr1.Field<string>("Item") == dr2.Field<string>("ItemCode")
let sum = dtItemSicorax.AsEnumerable().Where(x => x.Field<string>("Item") == dr2.Field<string>("ItemCode")).Sum(dr => dr.Field<decimal>("Quantity"))
select new
{
ID = dr2.Field<int>("ID"),
ItemName = dr2.Field<string>("ItemName"),
ItemCode = dr2.Field<string>("ItemCode"),
Qty = dr2.Field<int>("Qty"),
UpdatedQty = dr2.Field<int>("Qty") - sum,
ItemCodeName = dr1.Field<string>("Item"),
ItemQuantity = dr2.Field<int>("Qty") - sum,
InvoiceDate = dr1.Field<DateTime>("InvoiceDate"),
Sum = sum * -1,
}).GroupBy(x => x.ItemCodeName).Select(x => x.First()).ToList();
这很好。 现在,我正在创建另一个列表,该列表要从2个数据表中获取数据,其中数据表1中的“ Item” 等于不数据表2中的“ ItemCode” 。
我正在使用以下代码:
var sicochanges = (from dr1 in dtItemSicorax.AsEnumerable()
from dr2 in dtItemCloud.AsEnumerable()
where dr1.Field<string>("Item") != dr2.Field<string>("ItemCode")
let sumzero = 0
select new
{
ID = dr2.Field<int>("ID"),
ItemName = dr1.Field<string>("Item"),
ItemCode = dr1.Field<string>("Item"),
Qty = sumzero,
UpdatedQty = sumzero - Convert.ToInt32(dr1.Field<decimal>("Quantity")),
ItemCodeName = dr1.Field<string>("Item"),
ItemQuantity = Convert.ToInt32(dr1.Field<decimal>("Quantity")),
InvoiceDate = dr1.Field<DateTime>("InvoiceDate"),
Sum = sumzero - Convert.ToInt32(dr1.Field<decimal>("Quantity")),
}).GroupBy(x => x.ItemCode).Select(x => x.First()).ToList();
列表“ sicochanges”将返回数据表中的所有项目,而不是仅返回数据表1中不等于 “ ItemCode”的那些“ Item”来自数据表2 。
编辑1
在数据表1中,我有数据CADMIXAUTR06850,该数据在数据表2中找不到。 在数据表3中,我试图显示所有不常见的内容。但是数据表3正在显示所有项目,如图所示。
我的linq哪里有问题?
任何帮助将不胜感激。
答案 0 :(得分:0)
我不明白你的问题,但我试图简化你的问题;
这里有示例数据;
var d1 = new Dictionary<int, string>() { { 1, "a" }, { 2, "b" }, { 3, "c" }, };
var d2 = new Dictionary<int, string>() { { 1, "x" }, { 2, "y" }, { 3, "z" }, };
第一个查询;
var query1 = (
from _d1 in d1
from _d2 in d2
where _d1.Key == _d2.Key
let s = 0
select new { k1 = _d1.Key, v1 = _d1.Value, k2 = _d2.Key, v2 = _d2.Value, }
);
var group1 = query1.GroupBy(x => x.v1);
var result1 = group1.Select(x => x.First()).ToList();
第二个查询;
var query2 = (
from _d1 in d1
from _d2 in d2
where _d1.Key != _d2.Key
let s = 0
select new { k1 = _d1.Key, v1 = _d1.Value, k2 = _d2.Key, v2 = _d2.Value, }
);
var group2 = query2.GroupBy(x => x.k1);
var result2 = group2.Select(x => x.First()).ToList();
在第一个查询中,您不需要GroupBy
和Select
部分。 ToList
就足够了。 query1和result1的输出完全相同。
第二个查询执行外部联接,并且仅选择组的第一项。它选择所有d1项,但选择外部联接d2项。它选择1-2、2-1、3-1。我想您知道为什么它会选择这些值。
如果您的数据网格记录中没有共享相同项目名称的项目代码,则按项目代码或项目名称对数据进行分组都没有关系。
我希望这会对您有所帮助。
答案 1 :(得分:0)
您需要左连接以匹配Item和ItemCode值。参见this answer,并加上以下代码
List<string> inList1ButNotList2 = (from o in list1
join p in list2 on o equals p into t
from od in t.DefaultIfEmpty()
where od == null
select o).ToList<string>();
这里重要的一行是where od == null
,它获取不匹配的项目,where != null
将得到不匹配的项目。
Microsoft也有examples of joins
顺便说一句,为匹配的列赋予相同的名称可能是个好主意。