我有以下方法,我试图阻止人们改变querystring
以查看其他人的详细信息:
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
在Icollection<Vessel>
中产生3个容器,其中一个容器的VesselId
为6,这恰好是currentVessel
的VesselId但是匹配失败,方法返回false
。
我已经对类似的SO问题和MSDN文档做了一些阅读,我对这里发生的事情的理解是因为ICollection中ID为6的Vessel是我试图匹配的currentVessel的不同实例,引用导致不相等,并且与相等规则有关的内容不基于ID。
我的Person
模型包含public virtual ICollection<Vessel> Vessels { get; set; }
这是否意味着我必须在IEquatable
模型上实现Vessel
接口,然后覆盖Equals方法。
在此实例中,我希望基于id的自定义规则具有相等性。如何覆盖此方法?
答案 0 :(得分:3)
在这种情况下覆盖Equals
似乎有点矫枉过正,为什么不做呢
currentPerson.Vessels.Any(x => x.ID == currentVessel.ID)
答案 1 :(得分:2)
@james建议的解决方案不是最佳做法。
这里为什么如果你有一长串的船只应该添加到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;
}
}
更新
为什么我说这不是最佳做法,OP表示他有一个ICollection<Vessel>
可以转换为许多Generics集合,如List<T>
for例。
来自MSDN
调用多个通用集合对象的搜索方法时。其中一些类型及其方法包括以下内容:
答案 2 :(得分:1)
更改
if (currentPerson.Vessels.Contains(currentVessel))
{
return true;
}
else
return false;
到
return currentPerson.Vessels.Any(x => x.ID == currentVessel.ID)