Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.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/4/jquery-ui/2.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# 在IEquatable上重写Equals_C#_.net_Entity Framework - Fatal编程技术网

C# 在IEquatable上重写Equals

C# 在IEquatable上重写Equals,c#,.net,entity-framework,C#,.net,Entity Framework,我尝试使用以下方法阻止人们更改查询字符串,以查看其他人的详细信息: public static bool IsCurrentUserAuthorisedVessel(HttpRequest request) { Guid currentUser = GetCurrentUserId(); PersonRepository repo = new PersonRepository(); VesselRepository vesselRepo = new VesselRepos

我尝试使用以下方法阻止人们更改
查询字符串
,以查看其他人的详细信息:

public static bool IsCurrentUserAuthorisedVessel(HttpRequest request)
{
    Guid currentUser = GetCurrentUserId();
    PersonRepository repo = new PersonRepository();
    VesselRepository vesselRepo = new VesselRepository();

    Person currentPerson = repo.GetPersonByUser(currentUser);
    int qs = int.Parse(request.QueryString["VesselId"]);
    Vessel currentVessel = vesselRepo.GetVessel(qs);

    if (!String.IsNullOrEmpty(request.QueryString["VesselId"]))
    {       
        if (IsCurrentUserAdmin())
        {
            return true;  //Always return true for admin                  
        }
        else
        {
            if (currentPerson.Vessels.Contains(currentVessel))
            {
                return true;
            }
            else
                return false;
        }                
    }
    return true;
}
在本例中,我当前正在调试
currentPerson.Vessels
I集合中生成3个Vessels
其中一个的
VesselId
为6,它恰好也是
currentVessel
的VesselId,但是匹配失败,方法返回
false

我已经阅读了一些类似的SO问题和MSDN文档,我对这里发生的事情的理解是因为ICollection中ID为6的容器是我试图匹配的当前容器的不同实例,引用导致不相等,与相等规则有关的内容不基于ID

我的
Person
模型包含
公共虚拟ICollection容器{get;set;}
这是否意味着我必须在我的
容器
模型上实现
IEquatable
接口,然后覆盖Equals方法


在这个例子中,我需要基于id的自定义规则来实现相等。如何重写此方法?

重写
Equals
在这种情况下似乎有点过火,为什么不这样做呢

currentPerson.Vessels.Any(x => x.ID == currentVessel.ID)

在这种情况下重写
等于
似乎有点过分,为什么不这样做呢

currentPerson.Vessels.Any(x => x.ID == currentVessel.ID)
改变

if (currentPerson.Vessels.Contains(currentVessel))
{
    return true;
}
else
    return false;

改变

if (currentPerson.Vessels.Contains(currentVessel))
{
    return true;
}
else
    return false;


@james建议的解决方案不是最佳实践。 在这里,为什么如果你有一长串应该添加到
Hashset
contains方法中的容器,那么它只需要
O(1)
,因为它将在
GetHashCode
上被索引,而
。Any
是一个扩展方法,它应该遍历所有元素以找到正确的一个,并且成本将是
O(n)

你可以这样做

public class Vessel : IEquatable<Vessel>
    {
        public int Id { get; set; }

        public bool Equals(Vessel other)
        {
            return Id == other.Id ; 
        }

        public override int GetHashCode()
        {
            return Id;
        }
        public override bool Equals(object obj)
        {
            var vessel = obj as Vessel;
            return vessel != null && vessel.Id == this.Id;
        }
    }
公共级船舶:合格
{
公共int Id{get;set;}
公共布尔等于(其他船舶)
{
返回Id==other.Id;
}
公共覆盖int GetHashCode()
{
返回Id;
}
公共覆盖布尔等于(对象对象对象)
{
var血管=obj血管;
返回容器!=null&&vesser.Id==this.Id;
}
}
更新

我之所以说这不是最佳实践,是因为OP说他有一个
ICollection
,可以转换为许多泛型集合,例如
List

调用多个通用集合对象的搜索方法时。其中一些类型及其方法包括:

  • BinarySearch方法的一些泛型重载
  • List类的搜索方法,包括List.Contains(T)、List.IndexOf、List.LastIndexOf和List.Remove
  • Dictionary类的搜索方法,包括ContainsKey和Remove。 泛型LinkedList类的搜索方法,包括LinkedList.Contains和Remove

    • 由@james建议的解决方案不是最佳实践。 在这里,为什么如果你有一长串应该添加到
      Hashset
      contains方法中的容器,那么它只需要
      O(1)
      ,因为它将在
      GetHashCode
      上被索引,而
      。Any
      是一个扩展方法,它应该遍历所有元素以找到正确的一个,并且成本将是
      O(n)

      你可以这样做

      public class Vessel : IEquatable<Vessel>
          {
              public int Id { get; set; }
      
              public bool Equals(Vessel other)
              {
                  return Id == other.Id ; 
              }
      
              public override int GetHashCode()
              {
                  return Id;
              }
              public override bool Equals(object obj)
              {
                  var vessel = obj as Vessel;
                  return vessel != null && vessel.Id == this.Id;
              }
          }
      
      公共级船舶:合格
      {
      公共int Id{get;set;}
      公共布尔等于(其他船舶)
      {
      返回Id==other.Id;
      }
      公共覆盖int GetHashCode()
      {
      返回Id;
      }
      公共覆盖布尔等于(对象对象对象)
      {
      var血管=obj血管;
      返回容器!=null&&vesser.Id==this.Id;
      }
      }
      
      更新

      我之所以说这不是最佳实践,是因为OP说他有一个
      ICollection
      ,可以转换为许多泛型集合,例如
      List

      调用多个通用集合对象的搜索方法时。其中一些类型及其方法包括:

      • BinarySearch方法的一些泛型重载
      • List类的搜索方法,包括List.Contains(T)、List.IndexOf、List.LastIndexOf和List.Remove
      • Dictionary类的搜索方法,包括ContainsKey和Remove。 泛型LinkedList类的搜索方法,包括LinkedList.Contains和Remove

      请添加您正在使用的ORM(实体框架、NHibernate等)的标签。请添加您正在使用的ORM(实体框架、NHibernate等)的标签。谢谢,但我现在觉得自己像个白痴。容易当你知道如何嘿!谢谢,但我现在觉得自己像个白痴。容易当你知道如何嘿!将键入的值简化为:
      return Id==other.Id
      ,对象为return to
      return vessel!=空和等于(容器)
      。代码更少,逻辑也不会重复。声称使用
      Any
      这里的“不是一个好的解决方案”或“不是最佳实践”是毫无意义的。实现
      Equals
      的参数当然是有效的,但前提是性能/列表大小是OP没有提到的一个因素。将键入的Equals简化为:
      return Id==other.Id
      并且对象等于return to
      return vessel!=空和等于(容器)
      。代码更少,逻辑也不会重复。声称使用
      Any
      这里的“不是一个好的解决方案”或“不是最佳实践”是毫无意义的。实现
      Equals
      的参数当然是有效的,但只有当perfo