C# 林:帮我把这件事做好
我有以下专栏:C# 林:帮我把这件事做好,c#,.net,entity-framework,linq,C#,.net,Entity Framework,Linq,我有以下专栏: PersonId CategoryId SubCategoryId 1 61 47 2 61 48 3 61 0 424 4 61 0 425 5 84 55 6 61
PersonId CategoryId SubCategoryId
1 61 47
2 61 48
3 61 0 424
4 61 0 425
5 84 55
6 61 585
7 101 48
8 101 424
8 666 47
10 666 424
当我只搜索categoryId时,它是fine,subCategoryId时,它是fine,但当我同时搜索这两个时,比如categoryId=47&&subCategoryId=424。
我不能让它工作。。。在这种情况下,我只需要61人和666人
我可以用foreach,但这不是一个好主意
你们能帮我吗
if (ids.IdCategory != null && ids.IdSubCategory != null)
{
query = unitOfWork.PersonSkillsRepository.GetAll().Where(m => m.IdCategory == ids.IdCategory || m.IdSubCategory == ids.IdSubCategory);
}
else if (ids.IdCategory != null)
query = unitOfWork.PersonSkillsRepository.GetAll().Where(m => m.IdCategory == ids.IdCategory);
else
query = unitOfWork.PersonSkillsRepository.GetAll().Where(m => m.IdSubCategory == ids.IdSubCategory);
第一种情况是我得到了我想要的一半。。。但我想用一些方法来过滤,因为这样我也得到了101,我不知道如何查看人们是否同时拥有类别和子类别
我看不出一个没有foreach的方法能做到这一点
entities.Where(z => z.categoryId == 47 || z.subCategoryId == 424)
.GroupBy(z => z.personId)
.Where(z => z.Count() == 2)
.SelectMany(z => z.ToList());
可能会为您提供所需的数据
该查询表示“过滤数据并仅返回categoryId
为47或
=424”的数据”。然后将它们分组,并检查其中是否有两行(即一行用于类别ID
,一行用于子类别ID
)。
问题是在SubCategoryId列中,CategoryId=47没有任何值,这就是为什么当您同时搜索这两个字段时,不会给出任何结果。
尝试在CategoryId=47的子类别ID中添加任何值…编辑:
问题进一步澄清后,下面的代码应该可以工作
if (ids.IdCategory != null && ids.IdSubCategory != null)
{
query = unitOfWork.PersonSkillsRepository.GetAll().Where(m => (m.IdCategory == ids.IdCategory || m.IdSubCategory == ids.IdSubCategory) && m.IdPerson != 101);
}
首先,对于搜索条件,您的数据将返回null。下面是linq的一些示例,可能有助于此场景
你可以做不同种类的linq
List<CollectionObject> ColObj = CollectionObject.GetListCollectionObj();
List<CollectionObject> LinqResult = ColObj.Where(x => x.CategoryID == 47 && x.SubcategoryID == null).ToList();
List ColObj=CollectionObject.getListCollectionObject();
List LinqResult=ColObj.Where(x=>x.CategoryID==47&&x.SubcategoryID==null).ToList();
下面的代码可以很好地处理上面的linq语句
class CollectionObject
{
public int PersonID { get; set; }
public int? CategoryID { get; set; }
public int? SubcategoryID { get; set; }
public static List<CollectionObject> GetListCollectionObj()
{
List<CollectionObject> LColObj = new List<CollectionObject>();
LColObj.Add(new CollectionObject() { PersonID = 61, CategoryID = 47, SubcategoryID = null });
LColObj.Add(new CollectionObject() { PersonID = 61, CategoryID = 48, SubcategoryID = null });
LColObj.Add(new CollectionObject() { PersonID = 61, CategoryID = 0, SubcategoryID = 424 });
LColObj.Add(new CollectionObject() { PersonID = 61, CategoryID = 0, SubcategoryID = 425 });
LColObj.Add(new CollectionObject() { PersonID = 101, CategoryID = 48, SubcategoryID = null });
LColObj.Add(new CollectionObject() { PersonID = 101, CategoryID = null, SubcategoryID = 424 });
LColObj.Add(new CollectionObject() { PersonID = 666, CategoryID = 47, SubcategoryID = null });
LColObj.Add(new CollectionObject() { PersonID = 666, CategoryID = null, SubcategoryID = 424 });
return LColObj;
}
}
类集合对象
{
公共int PersonID{get;set;}
公共int?CategoryID{get;set;}
公共int?子类别id{get;set;}
公共静态列表GetListCollectionObj()
{
List LColObj=新列表();
添加(新的CollectionObject(){PersonID=61,CategoryID=47,SubcategoryID=null});
添加(新的CollectionObject(){PersonID=61,CategoryID=48,SubcategoryID=null});
添加(新的CollectionObject(){PersonID=61,CategoryID=0,SubcategoryID=424});
添加(新的CollectionObject(){PersonID=61,CategoryID=0,SubcategoryID=425});
添加(新的CollectionObject(){PersonID=101,CategoryID=48,SubcategoryID=null});
添加(新的CollectionObject(){PersonID=101,CategoryID=null,SubcategoryID=424});
添加(新的CollectionObject(){PersonID=666,CategoryID=47,SubcategoryID=null});
添加(新的CollectionObject(){PersonID=666,CategoryID=null,SubcategoryID=424});
返回LColObj;
}
}
您应该按人员id对所有人员技能进行分组,然后仅选择包含给定类别和子类别的组:
unitOfWork.PersonSkillsRepository.GetAll()
.GroupBy(p => p.PersonId)
.Where(g => g.Any(p => p.IdCategory == ids.IdCategory)
&& g.Any(p => p.IdSubCategory == ids.IdSubCategory))
.Select(g => g.Key)
对于优化,您可以在分组之前筛选出与任何给定类别不匹配的技能
unitOfWork.PersonSkillsRepository.GetAll()
.Where(p => p.IdCategory == ids.IdCategory
|| p.IdSubCategory == ids.IdSubCategory)
.GroupBy(p => p.PersonId)
.Where(g => g.Any(p => p.IdCategory == ids.IdCategory)
&& g.Any(p => p.IdSubCategory == ids.IdSubCategory))
.Select(g => g.Key)
下面的方法可以,但是您应该知道您存储数据的方式非常奇怪 (我的意思是,您的所有子类别不是都与一个类别相关吗?)
链接。好吧,当我在做我的工作时,似乎有3个人想出了同样的主意,所以我将把我的也加入进来——加上OP需要的关键补充
Func<IGrouping<int, CollectionObject>, bool> query =
gp=>
gp.Any(g=>g.CategoryID == 47) &&
gp.Any(g=>g.SubcategoryID == 424);
var q = (from p in ColObj
group p by p.PersonID)
.Where(query);
Func查询=
gp=>
gp.Any(g=>g.CategoryID==47)和
gp.Any(g=>g.Subcategory ID==424);
var q=(从ColObj中的p开始)
p组由p.PersonID创建)
.何处(查询);
有时,您需要将
query
替换为单字段版本。请提供一些您尝试过的代码。在您不太乱的情况下,Linq的性能与foreach循环一样好。在内部,它也会迭代IEnumerable。有很多网站都是这样工作的——你给出一些要求,然后有人为你实现这些要求(可能是为了一些钱)。但是StackOverflow以不同的方式工作-您尝试自己实现需求,如果您有一些问题(错误或意外结果),那么您可以给出问题描述,您当前的代码并请他人帮助您。这是因为您的示例中没有匹配行,categoryId=47&&subCategoryId=424
我编辑了我的帖子。我这样做了,101也来了,我想要两个问题是的,我的问题人。。。我正在尝试一种方法101不来太多,过滤器在某种程度上,集团。。。我不知道如果一行同时有47和424,那么它就不会包含在这个查询中。这是真的@Magnus。根据他的样本数据,这似乎不是一个可能的情况,但谢谢你提出它。@Magnus是的。。。。以前是这样的,但这次改变不是我的。。从我的老板那里得知,这个问题被标记为实体框架,“优化”可能只会使生成的查询复杂化,而不会带来任何性能提升。@Magnus取决于GetAll()
返回类型。通常它是一个已经从数据库中获取的IEnumerable
。分组前过滤掉大部分记录将加快分组速度并节省一些内存,同时检查g。Any
为O(N),这将随着组大小的增加而增加高返回类型iqeryable如果它是iqeryable
,“优化”将不会带来性能增益(甚至可能做相反的事情)。但是对于IEnumerable,我同意你的说法。@AntonioHenrique是的,如果是IQueryable
使用@Magnus建议的第一个版本。但请记住,公开IQueryable
通常会将数据访问逻辑扩展到应用程序上,并导致代码重复(不同位置的相同查询)
Func<IGrouping<int, CollectionObject>, bool> query =
gp=>
gp.Any(g=>g.CategoryID == 47) &&
gp.Any(g=>g.SubcategoryID == 424);
var q = (from p in ColObj
group p by p.PersonID)
.Where(query);