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)

现在我要做的是:

  1. 定义设置集
  2. 检查 setupSet 是否在 Usersc 中。
  3. 如果一个(来自我的 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.

所以有两种方法可以解决您的问题:

  1. 不要使用 List 的 Contains() 方法 - 并使用 LINQ 表达式比较对于理解 UserSet 的 2 个对象的相等性至关重要的属性 class

  2. 绝对更好 - 在您的 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);