Linq相当于Except

时间:2011-03-23 19:08:47

标签: c# linq

var keys = m_ASPxGridView.GetCurrentPageRowValues("ID", "SID");
var selectedkeyValues = m_ASPxGridView.GetSelectedFieldValues("ID", "SID");

var unselected=keys- selected values

var unselected=keys.Except(selectedkeyValues)// does not work

是否可以编写一个linq查询来获取密钥中的所有值[不存在于selectedkeyValues中?

4 个答案:

答案 0 :(得分:4)

BrokenGlasspst所说的一切都是正确的,但似乎还存在一些混淆,因为这些DevExpress方法会返回List<object>,其中{{1}是:

  

一个对象,它是一个字段值数组(如果通过fieldNames参数传递多个字段名称)或直接字段值(如果通过fieldNames参数传递单个字段名称)。 (Source Link

因此,由于您传递了多个字段名称,因此这样的代码应该可以工作:

object

正如我们一直在讨论的那样,如果两个集合的类型为// Get the current values var currentRowValues = m_ASPxGridView.GetCurrentPageRowValues("ID", "SID") // Cast each object to an array of objects .Cast<object[]>() // Project the two members of the array into an anonymous type .Select(x => new { ID = x[0].ToString(), SID = x[1].ToString() }); var selectedRowValues = m_ASPxGridView.GetSelectedFieldValues("ID", "SID") // Cast each object to an array of objects .Cast<object[]>() // Project the two members of the array into an anonymous type .Select(x => new { ID = x[0].ToString(), SID = x[1].ToString() }); // Compare the two collections to get the unselected row values var unselected = currentRowValues.Except(selectedRowValues); ,.NET将不知道如何比较它们。但是,如果将它们(使用object)投射到相同的匿名类型,它应该可以工作 - 我认为默认情况下它将使用值类型相等。

修改:根据来自 C# in Depth 的Jon Skeet:

  

在任何给定的程序集中,如果具有相同数量的属性,具有相同的名称和类型,则编译器将两个匿名对象初始值设定项视为相同的类型,并且它们以相同的顺序出现。

     

...

     

以自然方式确定同一匿名类型的两个实例之间的相等性,使用属性类型的Select方法依次比较每个属性值。

所以,如果我正确地阅读它,上面的代码应该完全按照你的要求进行。如果我不是,请告诉我; - )

答案 1 :(得分:3)

这符合Enumerable.Except中的描述。确保您的对象正确处理EqualsGetHashCode。这是LINQPad中的验证(2x - &gt; C#3 / .NET35):

var keys = new [] {"A", "B", "C"};
var selectedkeyValues = new [] {"A", "B"};
// var unselected=keys - selected values
var unselected=keys.Except(selectedkeyValues);
unselected.Dump(); // LINQPad support method -- remove in other contexts

结果:["C"]

另外,我很确定上面的订单有保证。考虑使用 “不起作用”来更新原始帖子。

快乐的编码。


正如Pandincus指出的那样,可以在重载中指定自定义比较:Enumerable.Except<<TSource> Method (IEnumerable<<TSource>, IEnumerable<<TSource>, IEqualityComparer<TSource>)

答案 2 :(得分:2)

问题在于您要比较复合键(ID,SID),并且这些方法将多个属性作为单个List<object>返回,因此您没有处理每个不同的财产分开。您应该可以根据它们的存储方式投射到匿名类型(请参阅documentation)。

假设在列表中的备用位置(ID,SID,ID,SID等)返回IDSID,您可以创建键的类型列表(如果ID类型为{ {1}}适当转换):

int

现在对List<object> keys = m_ASPxGridView.GetCurrentPageRowValues("ID", "SID"); var TypedKeys = keys.Zip(keys.Skip(1), (a, b) => new { Id = a.ToString(), SID = b.ToString() }) .Where((x, i) => i % 2 == 0) .ToList(); 执行相同操作,selectedkeyValues应该有效。

答案 3 :(得分:1)

尝试keys.Where(x => !selectedkeyValues.Contains(x));