ASP.NET 核心 MVC 列表<Model>.包含(模型)
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; }
}
还有一个静态的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)
现在我要做的是:
- 定义设置集
- 检查 setupSet 是否在 Usersc 中。
- 如果一个(来自我的 setupSet)在 Usersc 中,那么
3a) 如果 setupSet 在 Userc 中并且一切都相同那么什么都不做。
3b) 如果有什么不同,则删除 AllUsers 中的旧 UserSet 并插入新的
在代码中它看起来像这样:
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 中,但由于某些奇怪的原因,它总是 returns false,即使 setupSet 应该在其中。
even tho setupSet should be inside it
static
很少用于任何类型的 Asp.Net 项目是有原因的:有多个线程处理您的请求,如果它们都在争夺同一个 List<>
,那是灾难的根源。
要么使用同步集合(如 ConcurrentSet<>
或 ConcurrentBag<>
),要么使用粗糙的锁定机制,或者 某些东西 以确保你不t 践踏一个线程对另一个线程的列表访问。
或者更好的是,使用数据库来存储数据。这就是它的用途,大多数 DBMS 都是事务性的,因此它们可以为您安全地处理多线程访问。
这是因为您的代码行 Data.AllUser.Usersc.Contains(setupSec) 比较的是引用 - 而不是列表中对象属性的值。
您在顶部创建了 setupSet 对象,但未将其添加到列表中 - 因此此列表不包含它。尽管两个对象具有完全相同的 .net 属性值,但它们是两个不同的对象。因此 list.Contains() return false.
所以有两种方法可以解决您的问题:
不要使用 List 的 Contains() 方法 - 并使用 LINQ 表达式比较对于理解 UserSet 的 2 个对象的相等性至关重要的属性 class
绝对更好 - 在您的 UserSet class 中实现 Equals 方法,它将告诉 CLI 如果涉及到您的 class.[=13=,您将什么理解为 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;
因此在控制台中,我可以看到 "List Contains element"。如果您删除该覆盖 Equal 控制台将显示 "List does not contain the element".
最后但同样重要的是 Blindy 写道 - 使用线程安全集合。它将使您的示例更好(但是我不认为线程是您描述的问题)。
您还可以在 Entity Framework 中更深入地研究内存数据库 - 您不必使用静态元素集合(这是缓存数据库的模拟)创建静态 class我相信)。超级简单
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseInMemoryDatabase(databaseName: "My_DB")
.Options;
var context = new ApplicationDbContext(options);
我有这个class:
public class UserSet
{
public int One { get; set; }
public string Two { get; set; }
public string Three { get; set; }
}
还有一个静态的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)
现在我要做的是:
- 定义设置集
- 检查 setupSet 是否在 Usersc 中。
- 如果一个(来自我的 setupSet)在 Usersc 中,那么
3a) 如果 setupSet 在 Userc 中并且一切都相同那么什么都不做。
3b) 如果有什么不同,则删除 AllUsers 中的旧 UserSet 并插入新的
在代码中它看起来像这样:
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 中,但由于某些奇怪的原因,它总是 returns false,即使 setupSet 应该在其中。
even tho setupSet should be inside it
static
很少用于任何类型的 Asp.Net 项目是有原因的:有多个线程处理您的请求,如果它们都在争夺同一个 List<>
,那是灾难的根源。
要么使用同步集合(如 ConcurrentSet<>
或 ConcurrentBag<>
),要么使用粗糙的锁定机制,或者 某些东西 以确保你不t 践踏一个线程对另一个线程的列表访问。
或者更好的是,使用数据库来存储数据。这就是它的用途,大多数 DBMS 都是事务性的,因此它们可以为您安全地处理多线程访问。
这是因为您的代码行 Data.AllUser.Usersc.Contains(setupSec) 比较的是引用 - 而不是列表中对象属性的值。
您在顶部创建了 setupSet 对象,但未将其添加到列表中 - 因此此列表不包含它。尽管两个对象具有完全相同的 .net 属性值,但它们是两个不同的对象。因此 list.Contains() return false.
所以有两种方法可以解决您的问题:
不要使用 List 的 Contains() 方法 - 并使用 LINQ 表达式比较对于理解 UserSet 的 2 个对象的相等性至关重要的属性 class
绝对更好 - 在您的 UserSet class 中实现 Equals 方法,它将告诉 CLI 如果涉及到您的 class.[=13=,您将什么理解为 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;
因此在控制台中,我可以看到 "List Contains element"。如果您删除该覆盖 Equal 控制台将显示 "List does not contain the element".
最后但同样重要的是 Blindy 写道 - 使用线程安全集合。它将使您的示例更好(但是我不认为线程是您描述的问题)。
您还可以在 Entity Framework 中更深入地研究内存数据库 - 您不必使用静态元素集合(这是缓存数据库的模拟)创建静态 class我相信)。超级简单
var options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseInMemoryDatabase(databaseName: "My_DB")
.Options;
var context = new ApplicationDbContext(options);