C# 为什么";包括「;方法返回列表中的元素,就好像它不是?

C# 为什么";包括「;方法返回列表中的元素,就好像它不是?,c#,.net,list,contains,C#,.net,List,Contains,我的数据库中有一个产品表。此外,我的数据库中有品牌和类别表,它们彼此不相关。我想把这些联系起来。在表单UI中,当我单击其中一个类别时,应该是他们在相关类别中拥有产品的品牌 我试过这样做。首先,我使用GetList方法通过categoryID获取产品,然后获取这些产品的品牌,并将这些品牌添加到pblist列表(品牌类型)。但是,有些产品有相同的品牌,pblist有重复的品牌名称。我试图用contains方法解决这个问题,但它不起作用。另外,我在另一部分遇到了同样的问题,我试图从blist(所有品牌

我的数据库中有一个产品表。此外,我的数据库中有品牌和类别表,它们彼此不相关。我想把这些联系起来。在表单UI中,当我单击其中一个类别时,应该是他们在相关类别中拥有产品的品牌

我试过这样做。首先,我使用GetList方法通过categoryID获取产品,然后获取这些产品的品牌,并将这些品牌添加到pblist列表(品牌类型)。但是,有些产品有相同的品牌,pblist有重复的品牌名称。我试图用contains方法解决这个问题,但它不起作用。另外,我在另一部分遇到了同样的问题,我试图从blist(所有品牌的列表)中删除pblist中未包含的品牌。我试图通过以下代码从blist中删除该项:blist.RemoveAt(blist.IndexOf(item));但是这个也不起作用,它返回-1。但这个项目在blist中

 public class BrandVM : BaseVM
{
    public int ProductCount { get; set; }

}

 public class BaseVM
{
    public int ID { get; set; }
    public string Name { get; set; }

    public override string ToString()
    {
        return this.Name;
    }

 public class BrandService : ServiceBase, IBrandService
{


    public List<BrandVM> GetList(int Count)
    {
        try
        {
            var result = GetQuery();
            result = Count > 0 ? result.Take(Count) : result;

            return result.ToList();
        }
        catch (Exception ex)
        {

            return null;
        }
    }


public List<BrandVM> GetListByCatID(int pCatID)
    {
        var plist = productService.GetListByCatID(pCatID);
        List<BrandVM> pblist = new List<BrandVM>();
        foreach (var item in plist)
        {
            if (!pblist.Contains(item.Brand))
            {
                pblist.Add(item.Brand);
            }
        };

        var blist = GetList(0);
        var blistBackup = GetList(0);

        foreach (BrandVM item in blistBackup)
        {
            if (!pblist.Contains(item))
            {
                blist.Remove(item);
            }       
        };

        return blist;
    } 
公共类BrandVM:BaseVM
{
public int ProductCount{get;set;}
}
公共类BaseVM
{
公共int ID{get;set;}
公共字符串名称{get;set;}
公共重写字符串ToString()
{
返回此.Name;
}
公共类品牌服务:ServiceBase、IBrandService
{
公共列表GetList(整数计数)
{
尝试
{
var result=GetQuery();
结果=计数>0?结果。取(计数):结果;
返回result.ToList();
}
捕获(例外情况除外)
{
返回null;
}
}
公共列表GetListByCatID(int-pCatID)
{
var plist=productService.GetListByCatID(pCatID);
List pblist=新列表();
foreach(plist中的var项目)
{
如果(!pblist.Contains(item.Brand))
{
pblist.Add(项目.品牌);
}
};
var blist=GetList(0);
var blistBackup=GetList(0);
foreach(blistBackup中的BrandVM项)
{
如果(!pblist.Contains(项))
{
b.删除(项目);
}       
};
返回blist;
} 
这些是我与Brand相关的课程。在BrandService中,我分享了填充的方法,还有更多的方法需要填充

这是my ProductService中的方法: 我使用该方法按CategoryID(plist)提取产品列表

public List GetListByCatID(int-EntityID)
{
尝试
{
var result=GetQuery().Where(x=>x.Category.ID==EntityID);
返回result.ToList();
}
捕获(例外情况除外)
{
返回null;
}
}
此GetQuery方法用于ProductService,在其他服务中有一些区别,但也有相似之处

  private IQueryable<ProductVM> GetQuery()
    {
        return from p in DB.Products
               select new ProductVM
               {
                   ID = p.ProductID,
                   Name = p.ProductName,
                   UnitPrice = (decimal)p.UnitPrice,
                   Category =p.CategoryID==null?null:new CategoryVM()
                   {
                       ID = (int)p.CategoryID,
                       Name = p.Category.CategoryName
                   },
                   Brand = p.BrandID == null ? null :
                   new BrandVM
                   {
                           ID=(int)p.BrandID,
                           Name=p.Brand.BrandName,

                   }


               };
    }
private IQueryable GetQuery()
{
从p返回,单位为DB.Products
选择新产品虚拟机
{
ID=p.ProductID,
Name=p.ProductName,
单价=(十进制)p.单价,
Category=p.CategoryID==null?null:new CategoryVM()
{
ID=(int)p.CategoryID,
Name=p.Category.CategoryName
},
Brand=p.BrandID==null?null:
新品牌虚拟机
{
ID=(int)p.BrandID,
Name=p.Brand.BrandName,
}
};
}

由于您无法确保同一品牌的两个不同实例不相等, 从某种意义上说´.Equals(object other)´返回true, 'Contains'方法无法识别它们


我认为您可以通过覆盖
Brand
类中的.Equals来解决问题。

实体框架将Linq查询转换为SQL语句,这意味着
Equals
(和
GetHashCode
)不会用于比较数据库对象。但是,如果要比较这些对象的本地实例,则将使用这些方法进行比较

默认的
Equals
进行引用比较以确定相等,这从字面上说意味着一个类型的两个实例只有在它们都引用内存中完全相同的对象时才被认为相等

相反,我们希望使用
ID
属性进行相等比较,这意味着我们需要重写类的
Equals
(和
GetHashCode
)方法

下面是一个如何做到这一点的示例:

public class BaseVM
{
    public int ID { get; set; }
    public string Name { get; set; }

    public override string ToString()
    {
        return Name;
    }

    public override bool Equals(object obj)
    {
        return obj is BaseVM &&
               ((BaseVM) obj).ID == ID;
    }

    public override int GetHashCode()
    {
        return ID;
    }
}

或者,如果您不想修改该类(我建议这样做,因为它在任何地方都能解决此问题),您可以修改代码以过滤掉具有相同id(或名称)的任何品牌:


如果你可以共享一个,那就太棒了。请确保这是一段代码,我可以复制并粘贴到控制台应用程序中,并且可以按原样运行,无需修改。请确保在代码中指定输入,并明确预期的输出是什么。可能重复的是我的entity framework简介项目。该项目中有许多类和项目相互连接的解决方案。我认为,要运行这部分代码,我应该共享项目的完整解决方案。@ÖdülÖngören在链接的问题中看到了最上面的答案。您需要覆盖
Equals()
GetHashCode()
在您的
BrandVM
类中。@ÖdülÖngören或不按对象进行比较,而按描述进行比较。例如,使用
item.Brand.Name
进行比较。
public class BaseVM
{
    public int ID { get; set; }
    public string Name { get; set; }

    public override string ToString()
    {
        return Name;
    }

    public override bool Equals(object obj)
    {
        return obj is BaseVM &&
               ((BaseVM) obj).ID == ID;
    }

    public override int GetHashCode()
    {
        return ID;
    }
}
foreach (var item in plist)
{
    // Note: you could potentially use 'Name' instead of 'Id'
    if (!pblist.Any(productBrand => productBrand.Id == item.Brand.Id))
    {
        pblist.Add(item.Brand);
    }
}