C#LINQ使用where子句联接两个表

本文关键字:两个 使用 where 子句 C#LINQ | 更新日期: 2023-09-27 18:29:45

在使用where子句进行筛选时,我正在尝试join 2表。数据如下:

Category
Name Selected
A    0
B    1
C    0
SubCategory
Name ParentCategory Selected
s1   A              0
s2   B              1
s3   B              0

预期结果:

ParentCatName SubCatName SubCatSelected
B             s2         1
B             s3         0

实际结果:

ParentCatName SubCatName SubCatSelected
B             s2         1
B             s3         1  <-- should be 0

我使用的代码是:

IEnumerable<Category> result =
    from s in subcategories
    join c in categories
    on s.Parent equals c.Name into t
    from r in t.DefaultIfEmpty()
    where r == null ? false : r.Selected == true
    select new Category
    {
        Name = s.Name,
        Parent = (r == null ? string.Empty : r.Name),
        Selected = r.Selected
    };

编辑:帮助我弄清楚的是暂时重写它,以查看生成的数据结构。。。

var result =
    from s in subcategories
    join c in categories
    on s.Parent equals c.Name into t
    from r in t.DefaultIfEmpty()
    select new
    {
        s, r
    };

然后我找到了筛选所选类别的答案。请看下面的答案。。

C#LINQ使用where子句联接两个表

不要把事情搞得过于复杂。您试图实现的是根据所选类别筛选子类别。您可以通过以下简单的查询获得所需的结果

var result = from s in subcategories
             join c in categories on s.Parent equals c.Name
             where c.Selected
             select s;

看起来你设置错了。如果是r == null,那么您将其设置为false,否则您将在此处将其设置成truer.Select == true

只要阅读您的查询,您可能根本不需要where子句。

你可能想要这样的东西:

IEnumerable<Category> result =
    from s in subcategories
    join c in categories
    on s.Parent equals c.Name into t
    from r in t.DefaultIfEmpty()
    select new Category
    {
        Name = s.Name,
        Parent = (r == null ? string.Empty : r.Name),
        Selected = r.Selected
    };

或者,如果您需要进行null检查,请执行以下操作:

IEnumerable<Category> result =
    from s in subcategories
    join c in categories
    on s.Parent equals c.Name into t
    from r in t.DefaultIfEmpty()
    where r != null //I added the null check here
    select new Category
    {
        Name = s.Name,
        Parent = (r.Name), //I removed the null check here
        Selected = r.Selected
    };

我认为,您的t值包含类别列表。t必须包含子类别列表,然后您可以获取子类别的选定值。所以你总是选择值为1,请尝试这个:

IEnumerable<SubCategory> result =
    from c in categories
    join s in subcategories
    on c.Name equals s.Parent into t
    from r in t.DefaultIfEmpty()
    where r == null ? false : r.Selected == true
    select new SubCategory
    {
        Name = s.Name,
        Parent = (r == null ? string.Empty : r.Name),
        Selected = r.Selected
    };

OBS:我现在不尝试这个。但我认为有效。

好的。所以我又看了看,想出了这个。。。

IEnumerable<Category> result =
    from s in subcategories
    join c in categories.Where(f => f.Selected)
    on s.Parent equals c.Name into t
    from r in t.DefaultIfEmpty()
    where r == null ? false : true
    select new Category
    {
        Name = s.Name,
        Parent = s.Name,
        Selected = s.Selected,
    };

为了只筛选到选定父类别的联接,我在该数据的右侧添加了lambda表达式。