2014-11-04 93 views
1

我有以下的方法,我試圖用它來阻止人們改變querystring,以查看其他人的詳細信息:忽略equals上IEquatable

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產量3只船的例子在Icollection<Vessel>其中之一有一個VesselId是6,這也恰好是currentVessel的VesselId,但是匹配失敗,方法返回false

我已經對類似的SO問題和MSDN文檔做了一些閱讀,我對這裏發生的事情的理解是因爲在ICollection中具有6的ID的船隻是我試圖匹配的currentVessel的不同實例,該參考導致不相等,並且與平等規則不是基於ID有關。

我的Person模型包含public virtual ICollection<Vessel> Vessels { get; set; }這是否意味着我必須在我的Vessel模型上實現IEquatable接口,然後重寫Equals方法。

我希望我自己的自定義規則基於id在這種情況下相等。我如何覆蓋這個方法?

+0

請添加您正在使用的ORM(Entity Framework,NHibernate等)的標籤。 – 2014-11-04 14:36:36

回答

3

在這種情況下,重寫Equals似乎有點矯枉過正這裏,爲什麼不只是做

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

謝謝,但我現在感覺像個白癡。很容易當你知道嘿! – JsonStatham 2014-11-04 14:40:15

1

變化

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

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

通過@詹姆斯提出的解決方案是不最佳做法。 這裏爲什麼如果你有一長串船隻應該被添加到一個Hashset<Vessel>包含方法將只需花費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; 
     } 
    } 

更新

的原因,我有STA這並不是OP的最佳做法,它表示他有一個ICollection<Vessel>,可以將其轉換爲許多泛型集合,例如List<T>

MSDN

當一些通用的集合對象的搜索方法被調用。其中一些類型及其方法包括以下內容:

  • BinarySearch方法的一些泛型重載。
  • List類的搜索方法,包括List.Contains(T),List.IndexOf,List.LastIndexOf和List.Remove。
  • Dictionary類的搜索方法,包括ContainsKey和Remove。 通用LinkedList類的搜索方法,包括LinkedList.Contains和Remove。
+0

簡化鍵入的等於:'return Id == other.Id'並且對象等於返回到'return vessel!= null && Equals(vessel)'。較少的代碼,你不會複製邏輯。 – RobH 2014-11-04 14:46:01

+1

聲稱在這裏使用'Any'是「*不是一個好的解決方案*」或「*不是最佳實踐*」是無意義的。實現'Equals'的參數*當然是有效的,但只有*如果*性能/列表大小是一個因素--OP沒有提到。 – James 2014-11-04 14:52:33

+0

看到我的更新,我希望這將是有道理的 – 2014-11-04 15:52:27