Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用LINQ在两个表之间选择不同的值_C#_Linq_Dataset - Fatal编程技术网

C# 使用LINQ在两个表之间选择不同的值

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(),

我有一个数据集,看起来像下面的信息

我试图用尽可能多的可用信息填充对象

所以我想从顶部数据集中获取UnitNum 65002,其余的从单列表中获取

我的代码:

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);
}