我想通过Linq查询一个列表,但在我的示例中通过包含两个元素(名称、状态)的另一个列表进行筛选。这是受一个老问题的启发,我已经适应了我的问题。LINQ: "contains" and a Lambda query (在这个答案中,它只工作于一个元素,即状态)
我尝试使用“包含”方法,但没有成功地过滤我的列表。
我应该得到的结果只有两栋楼(两栋,五座),有人知道我在哪里停下来了吗?
谢谢
区块报价
public class Building
{
public enum StatusType
{
open,
closed,
weird,
};
public string Name { get; set; }
public StatusType Status { get; set; }
}
private static readonly List<Building> BuildingList = new List<Building>()
{
new Building() {Name = "one", Status = Building.StatusType.open},
new Building() {Name = "two", Status = Building.StatusType.closed},
new Building() {Name = "three", Status = Building.StatusType.weird},
new Building() {Name = "four", Status = Building.StatusType.open},
new Building() {Name = "five", Status = Building.StatusType.closed},
new Building() {Name = "six", Status = Building.StatusType.weird},
};
private void GetResult()
{
var buildingSelect = new List<Building>
{
new Building() {Name = "two", Status = Building.StatusType.closed},
new Building() {Name = "five", Status = Building.StatusType.closed}
};
var q = (from building in BuildingList
where buildingSelect.Contains(building.Name, building.Status)
select building).ToList();
dataGridView1.DataSource = q;
}发布于 2016-06-18 02:33:52
LINQ的主要问题是您正在尝试比较两个Buildings的相等性,因为Building没有实现IEquatable<Building>或覆盖object.Equals,所以LINQ只能通过它们的引用进行比较。
解决这个问题的一种方法是手动指定哪些属性可以按照@Wayne的答案进行相等的比较。
另一种方法是,如果Building实例要被值而不是引用等同,那么实现IEquatable<Building>并覆盖object.Equals。
public class Building : IEquatable<Building>
{
public Building(string name, StatusType status)
{
Name = name;
Status = status;
}
public enum StatusType
{
open,
closed,
weird,
};
public string Name { get; }
public StatusType Status { get; }
public static bool operator ==(Building left, Building right)
=> Equals(left, right);
public static bool operator !=(Building left, Building right)
=> !Equals(left, right);
public override bool Equals(object obj) => Equals(obj as Building);
public bool Equals(Building other)
{
if (ReferenceEquals(this, other))
{
return true;
}
if (ReferenceEquals(other, null) || GetType() != other.GetType())
{
return false;
}
return Name == other.Name && Status == other.Status;
}
public override int GetHashCode()
{
unchecked
{
int hash = 17;
hash = hash * 23 + Name?.GetHashCode() ?? 0;
hash = hash * 23 + Status.GetHashCode();
return hash;
}
}
}这样,您的原始代码就可以工作了,因为List.Contains现在将使用您的IEquatable<Building>实现来检查是否相等。
发布于 2016-06-18 01:40:44
你是说像这样的事?
var q = from b in BuildingList
from bs in buildingSelect
where b.Name == bs.Name && b.Status == bs.Status
select b;或者也许:
var q = from b in BuildingList
join bs in buildingSelect
on new { b.Name, b.Status } equals new { bs.Name, bs.Status }
select b;发布于 2016-06-18 02:37:10
如果这样做有意义的话,可以重写类本身中的等式。
或者通常使用Any()进行检查,如下所示:
var q = (from building in BuildingList
where buildingSelect.Any(b => b.Name == building.Name
&& b.Status == building.Status)
select building).ToList();https://stackoverflow.com/questions/37890816
复制相似问题