Lambda在加入时不相等

时间:2015-06-03 13:23:25

标签: c# .net lambda .net-4.5

名为Category的表1包含70条记录 表2名为FilterCategorys,包含0条记录(当前)。

我的lambda加入,我想只提取不匹配的记录,所以在这种情况下我希望得到70条记录。这是我不正确的Lambda:

var filteredList = categorys
            .Join(filterCategorys,
                x => x.Id,
                y => y.CategoryId,
                (x, y) => new { catgeory = x, filter = y })
            .Where(xy => xy.catgeory.Id != xy.filter.CategoryId)
            .Select(xy => new Category()
                        {
                            Name = xy.catgeory.Name,
                            Id = xy.catgeory.Id,
                            ParentCategoryId = xy.catgeory.ParentCategoryId
                        })
            .ToList();

我需要正确的语法吗?

5 个答案:

答案 0 :(得分:3)

不确定您是否需要使用lambdas(而不是查询语法),但我更喜欢具有外连接的语句的查询语法。

这应该是等价的:

var filteredList = (
    from c in Categorys 
    join fc in FilterCategorys on c.Id equals fc.CategoryId into outer
    from o in outer.DefaultIfEmpty()
    select new 
    {
        Category = new Category 
        {
            Name = c.Name, 
            Id = c.Id, 
            ParentCategoryId = c.ParentCategoryId
        },
        Exists = (o != null)
    })
    .Where(c => !c.Exists)
    .Select(c => c.Category);

答案 1 :(得分:2)

如果你想在纯粹的lambda中这样做:

var match = categorys.Join(filterCategorys, x => x.Id, y => y.CategoryId, (x, y) => new { Id = x.Id });
var filteredList = categorys.Where(x => !match.Contains(new {Id = x.Id}));

我还没有测量过它的性能,但对于70条记录,优化不是问题。

答案 2 :(得分:1)

我想出了一个解决方案,它不需要加入。

var currentIds = filterCategorys.Select(x => x.Id).ToList();
var filteredList = categorys.Where(x => !currentIds.Contains(x.Id));

非常类似@Zoff Dino的答案,不确定性能,也许有人想检查。

答案 3 :(得分:0)

试试这个:

var categories= ...
var filteredCategories=...
var allExceptFiltered = categories.Except(filteredCategories, new CategoryComparer()).ToList();

如果您没有提供自定义Comparer,那么框架无法知道2个Category对象是否相同(即使它们具有相同的ID),它只是认为它们是不同的对象(它检查引用相等) )

所以你必须将这个类添加到你的项目中:

public class CategoryComparer: IEqualityComparer<Category>
{
    public bool Equals(Category x, Category y)
    {
        if (x == null && y == null)
            return true;

        if (x == null)
            return false;

        if (y == null)
            return false;

        return x.CategoryId.GetHashCode() == y.CategoryId.GetHashCode();

    }

    public int GetHashCode(Category obj)
    {
        return obj.CategoryId.GetHashCode();
    }
}

<强>更新

同时查看Wyatt Earp的答案,知道如何进行外连接非常有用

更新2 你的问题是Join方法 在join.so之后“Where”子句被“调用”。在你根据ID选择那些具有不同ID的ID加入列表之后,这就是你没有得到任何结果的原因

答案 4 :(得分:0)

您可以画括号,它应该可以工作吗? .... Where(xy => (xy.catgeory.Id!= xy.filter.CategoryId)