Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 列表。除了不起作用之外_C#_Linq_List - Fatal编程技术网

C# 列表。除了不起作用之外

C# 列表。除了不起作用之外,c#,linq,list,C#,Linq,List,我尝试减去2个列表,如下面的代码,assignUsers有3条记录,assignedUsers有2行。在方法之外的之后,我仍然得到了3行,尽管我应该得到1条记录,因为assignedUsers中的2行与assignUsers var users = accountApp.GetUsersByAccountId(context.GetUserData().AccountId); List<AssignUserViewModel> assignUsers = Mapper.Map&l

我尝试减去2个列表,如下面的代码,
assignUsers
有3条记录,
assignedUsers
有2行。在
方法之外的
之后,我仍然得到了3行,尽管我应该得到1条记录,因为
assignedUsers
中的2行与
assignUsers

 var users = accountApp.GetUsersByAccountId(context.GetUserData().AccountId);
 List<AssignUserViewModel> assignUsers = Mapper.Map<List<AssignUserViewModel>>(users).ToList();
 var mailUsers = mailApp.GetMailAssignedByMailId(id).Select(m => new { m.UserId, m.User.Name }).ToList();
 List<AssignUserViewModel> assignedUsers = mailUsers.Select(Mapper.DynamicMap<AssignUserViewModel>).ToList();
 assignUsers = assignUsers.Except(assignedUsers).ToList();
var users=accountApp.GetUsersByAccountId(context.GetUserData().AccountId);
List assignUsers=Mapper.Map(users.ToList();
var mailUsers=mailApp.getmailsassignedbymailid(id).Select(m=>new{m.UserId,m.User.Name}).ToList();
List assignedUsers=mailUsers.Select(Mapper.DynamicMap.ToList();
assignUsers=assignUsers.Except(assignedUsers.ToList();

为了使
方法按预期工作,类
AssignUserViewModel
必须正确重写
GetHashCode
Equals
方法

例如,如果
AssignUserViewModel
对象是由其
Id
唯一定义的,则应以以下方式定义类:

class AssignUserViewModel
{
    // other methods...


    public override int GetHashCode()
    {
        return this.Id.GetHashCode();
    }
    public override bool Equals(object obj)
    {
        if (!(obj is AssignUserViewModel))
            throw new ArgumentException("obj is not an AssignUserViewModel");
        var usr = obj as AssignUserViewModel;
        if (usr == null)
            return false;
        return this.Id.Equals(usr.Id);
    }
}
否则,如果您不能/不想更改类实现,则可以实现
IEqualityComparer
并将其传递给
方法,但
除外,例如:

class AssignUserViewModelEqualityComparer : IEqualityComparer<AssignUserViewModel>
{
    public bool Equals(AssignUserViewModel x, AssignUserViewModel y)
    {
        if (object.ReferenceEquals(x, y))
            return true;
        if(x == null || y == null)
            return false;
        return x.Id.Equals(y.Id);
    }

    public int GetHashCode(AssignUserViewModel obj)
    {
        return obj.Id.GetHashCode();
    }
}
为什么会这样? 使用(Distinct、Except、Intersect、Union)时,Linq需要比较序列元素是否相等。默认情况下,Linq使用和方法来比较元素。如果这些方法在您的类型中未被重写,则将使用基类的实现,该实现通过引用相等来比较对象。默认实现保证相同引用的两个对象具有相同的哈希代码(因此被认为是相等的)。这是你的案子
Mapper
类创建具有不同引用的
AssignUserViewModel
对象的新实例,这些对象不能被视为相等(即使所有字段值都相同)

那么,我们该怎么办呢

  • 重写类中的
    Equals
    GetHashCode
    方法。这取决于您如何平等对待对象—所有字段,或只是标识。Linq将使用您的方法来比较元素

  • 提供您自己的比较器(当您无法修改对象并覆盖
    Equals
    GetHashCode
    时,通常是这种情况)。是的,所有Linq集合操作都有两个重载—一个使用默认比较器,另一个接受您的重载

  • 使用匿名类型。所有匿名类型都已经生成了方法
    Equals
    GetHashCode
    ,它们使用所有属性的比较来确定对象是否相等。在这种情况下,您不需要修改类型也不需要创建比较器

因此,您已经有了前两种方法的示例,这里是最后一种:

var assignUsers = accountApp.GetUsersByAccountId(context.GetUserData().AccountId)
                            .Select(u => new { u.UserId, u.Name });

var assignedUsers = mailApp.GetMailAssignedByMailId(id)
                           .Select(m => new { m.UserId, m.User.Name });

var assignUsers = assignUser.Except(assignedUsers);
// do not map until here
List<AssignUserViewModel> result = 
             assignUsers.Select(Mapper.DynamicMap<AssignUserViewModel>).ToList();
var assignUsers=accountApp.GetUsersByAccountId(context.GetUserData().AccountId)
.Select(u=>new{u.UserId,u.Name});
var assignedUsers=mailApp.GetMailAssignedByMailId(id)
.Select(m=>new{m.UserId,m.User.Name});
var assignUsers=assignUser.Except(assignedUsers);
//在这里之前不要绘制地图
列表结果=
assignUsers.Select(Mapper.DynamicMap.ToList();

您的映射程序可能正在丢失引用,并且该类型可能没有定义其他比较器。请使用IComparer编写一个比较函数。@leppie您应该将其作为答案发布:)如何正确地将匿名类型映射到其他类型?如果是这样的话。稍微更改了相等比较器Equals,以考虑空值。
var assignUsers = accountApp.GetUsersByAccountId(context.GetUserData().AccountId)
                            .Select(u => new { u.UserId, u.Name });

var assignedUsers = mailApp.GetMailAssignedByMailId(id)
                           .Select(m => new { m.UserId, m.User.Name });

var assignUsers = assignUser.Except(assignedUsers);
// do not map until here
List<AssignUserViewModel> result = 
             assignUsers.Select(Mapper.DynamicMap<AssignUserViewModel>).ToList();