为什么“包含”方法返回列表中的元素就好像不是这样?

时间:2019-09-12 23:09:55

标签: c# .net list contains

我的数据库中有一个产品表。另外,我的数据库中有彼此不相关的品牌和类别表。我想把这些联系起来。在表单UI中,当我单击“类别”之一时,应该出现其在相关类别中具有产品的品牌。

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

 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;
    } 

这些是我与品牌相关的课程。在BrandService中,我共享了fill方法,还有更多方法可以填充。

这是我的ProductService中的方法: 我使用该方法通过CategoryID(plist)拉出产品列表

public List<ProductVM> GetListByCatID(int EntityID)
    {
        try
        {
            var result = GetQuery().Where(x => x.Category.ID==EntityID);

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

            return null;
        }
    }

此用于ProductService的GetQuery方法,在其他服务中有一些区别,但有相似之处

  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,

                   }


               };
    }

2 个答案:

答案 0 :(得分:1)

实体框架会将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(或名称)的所有品牌:

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);
    }
}

答案 1 :(得分:0)

由于您不能确保同一品牌的两个不同实例不相等, 在“。等于(对象其他)”返回true的意义上, “ .Contains”方法无法识别它们。

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

相关问题