c# - 为什么“包含”方法返回一个在列表中的元素,就好像它不在?
问题描述
我的数据库中有一个产品表。此外,我的数据库中有品牌和类别表,它们彼此不相关。我想把这些联系起来。当我单击其中一个类别时,在表单 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 中,我分享了填充方法,还有更多方法可以填充。
这是我的 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;
}
}
这个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,
}
};
}
解决方案
实体框架会将 Linq 查询转换为 SQL 语句,这意味着Equals
(and GetHashCode
) 不会用于数据库对象的比较。但是,如果您要比较这些对象的本地实例,那么这些方法将用于比较。
默认值Equals
会进行引用比较以确定相等性,这实际上意味着一个类型的两个实例只有在它们都引用内存中完全相同的对象时才被认为是相等的。
相反,我们希望使用该ID
属性进行相等比较,这意味着我们需要覆盖类的Equals
(and 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);
}
}
推荐阅读
- javascript - 如何在反应中实现动态div的拖放?
- perl - die 函数与 use 函数一起使用时会产生语法错误
- javascript - 过滤器从数组到 Json 格式的转换,用于 devextreme
- c# - 如果一个函数依赖于另一个函数,你如何用模拟数据替换该内部函数以进行单元测试?
- scala - 如何实现生命周期 PostStop?
- javascript - 无法获取未定义或空引用的属性“textContent”
- javascript - 如何不导出对象中的私有函数?
- python - 为什么只有一半的预期输出使用纹理坐标环绕模式,例如来自 SB OpenGL
- asp.net-core - 带有 OpenID Connect 的 ASP.Net Core 2.1:未找到相关状态属性错误
- python - 如何让 Pyglet 媒体队列继续播放?