为什么我在执行交集时得不到结果?
Why am I not getting results when performing an intersection?
用户class:
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);
其中 returns 0 个结果。
我知道我可以通过使用 join 来完成类似的事情,但我想使用 Intersect,因为 A) 这最终会在某些数据库代码上起作用,我们想使用这个函数(太长了,无法解释为什么)和 B) 我只是很好奇为什么 Intersect 在这里不起作用。
var both = from l in usersL
join r in usersR on l.ID equals r.ID
select l;
.Net 提供预定义类型的比较逻辑。在您的连接查询的情况下,您正在连接(比较)两个 Int 类型的 ID(预定义类型)
var both = from l in usersL
join r in usersR on l.ID equals r.ID
select l;
在交叉查询的情况下,您正在尝试比较用户类型的两个用户定义的自定义对象。因此,您需要提供自己的自定义比较实现逻辑。
有 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);
}
}
希望这对您有所帮助。
这是对@sundeep 的回应,他说 "Now regards to your 2nd question... "(我希望你能 link 发表评论)——我只是创建一个新答案,因为我不想毁了我原来问题的背景
用户 class 实施 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();
}
}
交叉点returns没有行:
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);
用户class:
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);
其中 returns 0 个结果。
我知道我可以通过使用 join 来完成类似的事情,但我想使用 Intersect,因为 A) 这最终会在某些数据库代码上起作用,我们想使用这个函数(太长了,无法解释为什么)和 B) 我只是很好奇为什么 Intersect 在这里不起作用。
var both = from l in usersL
join r in usersR on l.ID equals r.ID
select l;
.Net 提供预定义类型的比较逻辑。在您的连接查询的情况下,您正在连接(比较)两个 Int 类型的 ID(预定义类型)
var both = from l in usersL
join r in usersR on l.ID equals r.ID
select l;
在交叉查询的情况下,您正在尝试比较用户类型的两个用户定义的自定义对象。因此,您需要提供自己的自定义比较实现逻辑。
有 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);
}
}
希望这对您有所帮助。
这是对@sundeep 的回应,他说 "Now regards to your 2nd question... "(我希望你能 link 发表评论)——我只是创建一个新答案,因为我不想毁了我原来问题的背景
用户 class 实施 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();
}
}
交叉点returns没有行:
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);