![](/img/trans.png)
[英]form for a model that contains a list property in asp.net core 3 MVC
[英]ASP.NET Core MVC List<Model>.Contains(Model)
我有这个 class:
public class UserSet
{
public int One { get; set; }
public string Two { get; set; }
public string Three { get; set; }
}
还有一个 static class:
public static class AllUsers
{
public static List<UserSet> Usersc = new List<UserSet>();
}
我总是创建新的UserSet
,然后将其存储在Usersc
中。 基本上我这样做:
Data.UserSet setupSet = new Data.UserSet()
{
One = name,
Two = OsCislo,
Three = User.Identity.Name
};
然后我存储它。
Data.AllUsers.Usersc.Add(setupSet)
现在我想做的是:
在代码中,它将如下所示:
Data.UserSet setupSet = new Data.UserSet()
{
One = name,
Two = OsCislo,
Three = User.Identity.Name
};
if (Data.AllUsers.Usersc.Select(s => s.One).ToList().Contains(User.Identity.Name))
{
// Always returns false for some reason
if (!Data.AllUser.Usersc.Contains(setupSet))
{
Data.AllUsers.Usersc.Remove(Data.AllUsers.Usersc.Where(s => s.One == User.Identity.Name).ToList().First());
Data.AllUsers.Usersc.Add(setupSet);
}
}
else
{
Data.AllUsers.Usersc.Add(setupSet);
}
如您所见,问题出在我的 if 语句中,我尝试获取 setupSet 是否在 Usersc 中,但由于某些奇怪的原因,即使 setupSet 应该在其中,它总是返回 false。
即使 setupSet 应该在里面
static
在任何类型的 Asp.Net 项目中很少使用是有原因的:有多个线程处理您的请求,如果它们都在同一个List<>
上争吵,那就是灾难的根源。
要么使用同步集合(如ConcurrentSet<>
或ConcurrentBag<>
),要么使用粗略的锁定机制,或者确保您不会践踏另一个线程的列表访问权限。
或者更好的是,使用数据库来存储数据。 这就是它的用途,而且大多数 DBMS 都是事务性的,因此它们为您安全地处理多线程访问。
这是因为您的代码行 Data.AllUser.Usersc.Contains(setupSec) 比较引用 - 而不是列表中对象的属性值。
您在顶部创建 setupSet object 而不将其添加到列表中 - 因此此列表不包含它。 尽管两个对象具有完全相同的 .net 属性值,但它们是两个不同的对象。 因此 list.Contains() 返回 false。
因此,要解决您的问题,有两种方法:
不要使用 List 的 Contains() 方法 - 并使用 LINQ 表达式比较对您理解 UserSet class 的 2 个对象的相等性至关重要的属性
绝对更好 - 在您的 UserSet class 中实现 Equals 方法,这将告诉 CLI 如果涉及到您的 class,您将什么理解为 EQUAL。
看看下面的代码(请记住,这是一个幼稚的实现):
void Main()
{
var myList = new List<SomeClass>();
var o1 = new SomeClass{SomeProperty = "foo"};
myList.Add(o1);
var o2 = new SomeClass{SomeProperty = "foo"};
if(myList.Contains(o2))
{
"List Contains element".Dump();
}
else{
"List does not contain element".Dump();
}
}
private class SomeClass{
public string SomeProperty {get;set;}
public override bool Equals(object obj)
{
var casted = obj as SomeClass;
if(casted == null) return false;
if(string.Equals(casted.SomeProperty, this.SomeProperty)) return true;
return false;
}
}
在这里,我告诉 .NET 通过覆盖 {public bool Equals(object obj)} 方法,我的 SomeClass 的 2 个实例相等对我意味着什么。
在该方法内部,如果 SomeProperty 的值相同,我会写 2 个对象相等。
if(string.Equals(casted.SomeProperty, this.SomeProperty)) return true;
因此在控制台中,我可以看到“列表包含元素”。 如果您删除该覆盖 Equal,控制台将显示“列表不包含该元素”。
最后但并非最不重要的是,正如 Blindy 所写 - 使用线程安全集合。 它将使您的示例更好(但是我不相信线程是您描述的问题)。
您还可以深入研究 Entity Framework 中的内存数据库 - 您不必创建 static class 和 static 元素集合(相信是缓存数据库的模拟)。 超级简单
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseInMemoryDatabase(databaseName: "My_DB")
.Options;
var context = new ApplicationDbContext(options);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.