我有两个Users类列表,即UsersExisting,UsersToUpdate。 类结构如下所示。
public class Users
{
public string Name{get;set;}
public Roles[] AvailableRoles{get;set;}
}
class Roles
{
public int Serial{get;set;}
public string Name{get;set;}
public bool IsActive{get;set;}
}
我必须检查UsersToUpdate是否已经具有UsersExisting的所有角色详细信息。
EG。这是清单
UsersExisting.AvailableRoles={{1,"admin",true},{2,"hr",false},{3,"it",true}};
UsersToUpdate.AvailableRoles={{1,"admin",true},{2,"hr",false},{3,"it",true},{4,"finance",false}};
如何使用LINQ执行此操作。
我这样做。
bool isUsersUpdated = !UsersExisting.AvailableRoles
.Except(UsersToUpdate.AvailableRoles).Any();
这是抛出错误。
答案 0 :(得分:2)
您可以将Serial
数字与Except
进行比较,这些数字似乎是角色标识符:
IEnumerable<int> existingRoles = UsersExisting
.SelectMany(u => u.AvailableRoles.Select(r => r.Serial));
IEnumerable<int> updatingRoles = UsersToUpdate
.SelectMany(u => u.AvailableRoles.Select(r => r.Serial));
bool isUsersUpdated = !existingRoles.Except(updatingRoles).Any();
我必须比较序列号和名称。
然后最好的方法是覆盖Equals
中的GetHashCode
+ Roles
或提供可以传递给IEqualityComparer<Roles>
的自定义Enumerable.Except
。另一种方法是使用我的代码,但选择包含序列号+名称的匿名类型:
IEnumerable<int> existingRoles = UsersExisting
.SelectMany(u => u.AvailableRoles.Select(r => new {r.Serial,r.Name}));
IEnumerable<int> updatingRoles = UsersToUpdate
.SelectMany(u => u.AvailableRoles.Select(r => new {r.Serial,r.Name}));
bool isUsersUpdated = !existingRoles.Except(updatingRoles).Any();
答案 1 :(得分:1)
您必须覆盖班级Equals
中的方法GetHashCode
和Roles
才能使其发挥作用。这是因为Except
使用这些方法来确定对象是否彼此相等。
在此处了解如何覆盖这些方法:
https://msdn.microsoft.com/en-US/library/ms173147(v=vs.80).aspx
答案 2 :(得分:0)
如果要比较某些自定义数据类型的对象序列,请在类中实现IEquatable泛型接口。此外,您必须覆盖Roles类中的Equals和GetHashCode方法。
我在这里创建了this dotnet小提琴。你可以看到程序的输出。
using System;
using System.Linq;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
Console.WriteLine("Hello World");
var availbleRoles = new List<Roles>();
availbleRoles.Add(new Roles() { Serial = 1, Name = "Test 1", IsActive = true });
availbleRoles.Add(new Roles() { Serial = 2, Name = "Test 2", IsActive = true });
availbleRoles.Add(new Roles() { Serial = 4, Name = "Test 4", IsActive = true });
var updatedRoles = new List<Roles>();
updatedRoles.Add(new Roles() { Serial = 1, Name = "Test 1", IsActive = true });
updatedRoles.Add(new Roles() { Serial = 2, Name = "Test 2", IsActive = true });
updatedRoles.Add(new Roles() { Serial = 3, Name = "Test 3", IsActive = true });
updatedRoles.Add(new Roles() { Serial = 4, Name = "Test 4", IsActive = true });
var roles = updatedRoles.Except(availbleRoles);
foreach (var role in roles)
{
Console.WriteLine("Serial : " + role.Serial + " Name : " + role.Name);
}
bool isRoleUpdated = roles.Any();
Console.WriteLine("Role Updated : " + isRoleUpdated);
}
}
public class Roles : System.IEquatable<Roles>
{
public int Serial {get; set;}
public string Name {get;set;}
public bool IsActive {get;set;}
public bool Equals(Roles other)
{
//Check whether the compared object is null.
if (Object.ReferenceEquals(other, null)) return false;
//Check whether the compared object references the same data.
if (Object.ReferenceEquals(this, other)) return true;
//Check whether the products' properties are equal.
return Serial.Equals(other.Serial) && Name.Equals(other.Name);
}
// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public override int GetHashCode()
{
//Get hash code for the Name field if it is not null.
int hashRoleName = Name == null ? 0 : Name.GetHashCode();
// Get hash code for the Serial field.
int hashSerial = Serial.GetHashCode();
//Calculate the hash code for the Role.
return hashSerial ^ hashRoleName;
}
}
public class Users
{
public string Name {get;set;}
public Roles[] AvailableRoles { get; set; }
}