用户类:
public class User
{
public int ID { get; set; }
public string Email { get; set; }
}
代码:
var usersL = new List<User>()
{
new User{ID = 1,Email = "abc@foo.com"},
new User{ID = 2,Email = "def@foo.com"}
};
var usersR = new List<User>()
{
new User{ID = 1,Email = "abc@foo.com"},
new User{ID = 2,Email = "def@foo.com"}
};
var both = (from l in usersL select l)
.Intersect(from users in usersR select users);
foreach (var r in both)
Console.WriteLine(r.Email);
返回0结果。
我知道我可以通过使用 join 来完成类似的事情,但我想使用Intersect,因为A)这最终会对某些数据库代码起作用,我们想要使用这个函数(太长时间)进入为什么)和B)我只是很好奇为什么Intersect不在这里工作。
var both = from l in usersL
join r in usersR on l.ID equals r.ID
select l;
答案 0 :(得分:1)
.Net为预定义类型提供比较逻辑。如果您的连接查询正在加入(比较)两个类型为Int(预定义类型)的ID
var both = from l in usersL
join r in usersR on l.ID equals r.ID
select l;
如果是交叉查询,则尝试比较两个用户定义的User类型的自定义对象。因此,您需要提供自己的自定义比较实现逻辑。
2种方式可以解决这个问题......
选项1: 实施IEqualityComparer
public class User
{
public int ID { get; set; }
public string Email { get; set; }
}
public class MyEqualityComparer : IEqualityComparer<User>
{
public bool Equals(User x, User y)
{
if (object.ReferenceEquals(x, y))
return true;
if (x == null || y == null)
return false;
return x.ID.Equals(y.ID) &&
x.Email.Equals(y.Email);
}
public int GetHashCode(User u)
{
return new { u.ID, u.Email }.GetHashCode();
}
}
class Program
{
static void Main(string[] args)
{
var usersL = new List<User>()
{
new User{ID = 1,Email = "abc@foo.com"},
new User{ID = 2,Email = "def@foo.com"}
};
var usersR = new List<User>()
{
new User{ID = 1,Email = "abc@foo.com"},
new User{ID = 2,Email = "def@foo.com"}
};
var both = (from l in usersL select l)
.Intersect(from users in usersR select users, new MyEqualityComparer());
foreach (var r in both)
Console.WriteLine(r.Email);
}
}
选项2 :覆盖自定义对象本身中的Equals和GetHashcode方法
public class User
{
public int ID { get; set; }
public string Email { get; set; }
public override bool Equals(Object obj)
{
// Check for null values and compare run-time types.
if (obj == null || GetType() != obj.GetType())
return false;
User x = (User)obj;
return (ID == x.ID) && (Email == x.Email);
}
public override int GetHashCode()
{
return new { ID, Email }.GetHashCode();
}
}
class Program
{
static void Main(string[] args)
{
var usersL = new List<User>()
{
new User{ID = 1,Email = "abc@foo.com"},
new User{ID = 2,Email = "def@foo.com"}
};
var usersR = new List<User>()
{
new User{ID = 1,Email = "abc@foo.com"},
new User{ID = 2,Email = "def@foo.com"}
};
var both = (from l in usersL select l)
.Intersect(from users in usersR select users);
foreach (var r in both)
Console.WriteLine(r.Email);
}
}
希望这有帮助。
答案 1 :(得分:0)
这是对@sundeep的回应,他说&#34;现在关注你的第二个问题......&#34; (我希望你能链接到评论) - 我只是创建一个新的答案,因为我不想破坏我原来问题的背景
实现 IEqualityComparer
的用户类public class User : IEqualityComparer<User>
{
public int ID { get; set; }
public string Email { get; set; }
public bool Equals(User x, User y)
{
if (object.ReferenceEquals(x, y))
return true;
if (x == null || y == null)
return false;
return x.ID.Equals(y.ID) &&
x.Email.Equals(y.Email);
}
public int GetHashCode(User obj)
{
return new { obj.ID, obj.Email }.GetHashCode();
}
}
交点不返回任何行:
var usersL = new List<User>()
{
new User{ID = 1,Email = "abc@foo.com"},
new User{ID = 2,Email = "def@foo.com"}
};
var usersR = new List<User>()
{
new User{ID = 1,Email = "abc@foo.com"},
new User{ID = 2,Email = "def@foo.com"}
};
var both = (from l in usersL select l)
.Intersect(from users in usersR select users);
foreach (var r in both)
Console.WriteLine(r.Email);