使用LINQ和MVC C#根据条件将过滤器应用于表

时间:2016-11-10 10:19:59

标签: c# asp.net-mvc linq

我正在尝试根据几个条件列表创建记录列表(合作伙伴)。问题是LINQ生成的SQL选择的是至少遵守其中一个条件的合作伙伴,我只希望合作伙伴尊重必须应用的条件(serviceId或/和brandId和/或TraillerService)。 / p>

模型(简化):

public class Partner
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<PartnerServiceBrand> PartnerServiceBrands { get; set; }

}

// A partner can have multiple services, brands and in each case, can have, or not have trailler service
public class PartnerServiceBrand
{
    [Key]
    public int Id { get; set; }

    public virtual Partner Partner { get; set; }
    public virtual Service Service { get; set; }
    public virtual Brand Brand { get; set; }

    public bool TrailerService { get; set; }
}

public class Service
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<PartnerServiceBrand> PartnerServiceBrands { get; set; }
}

public class Brand
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<PartnerServiceBrand> PartnerServiceBrands { get; set; }
}

我想根据我拥有的过滤器应用条件:

IQueryable<Partner> partners = dbContext.Partners;

if (search.ServiceId > 0)
{
    partners = dbContext.Partners.Where(p => p.PartnerServiceBrands.Select(psb => psb.Service.Id).Contains(search.ServiceId));
}

if (search.BrandId > 0)
{
    partners = partners.Where(p => p.PartnerServiceBrands.Select(psb => psb.Brand.Id).Contains(search.BrandId));
}

if (search.TrailerService == true)
{
    partners = partners.Where(x => x.PartnerServiceBrands.Any(y => y.TrailerService == true));
}

我得到的查询是:

SELECT[Extent1].[Id] AS[Id], [Extent1].[Name] AS[Name]
    WHERE(EXISTS (SELECT 1 AS[C1]
    FROM [dbo].[PartnerServiceBrands] AS [Extent2]
    WHERE ([Extent1].[Id] = [Extent2].[Partner_Id]) AND([Extent2].[Service_Id] = 7)
                        )) AND(EXISTS (SELECT 1 AS[C1]
                                        FROM [dbo].[PartnerServiceBrands] AS [Extent3]
                                        WHERE ([Extent1].[Id] = [Extent3].[Partner_Id]) AND([Extent3].[Brand_Id] = 1153)
                        )) AND(EXISTS (SELECT 1 AS[C1]
                                        FROM [dbo].[PartnerServiceBrands] AS [Extent4]
                                        WHERE ([Extent1].[Id] = [Extent4].[Partner_Id]) AND(1 = [Extent4].[TrailerService])
                        ))

通过这个查询,我得到了拥有预告片服务的至少1项服务的合作伙伴,而这不是我想要的。我只想要尊重所有条件的合作伙伴。

2 个答案:

答案 0 :(得分:1)

尝试这样的事情:

var baseQuery = db.PartnerServiceBrands.AsNoTracking().AsQueryable();

if(filterTrailer.hasValue){
    baseQuery = baseQuery.Where(x=> x.TrailerService == filterTrailer.Value);
}

if(filterServiceId.hasValue){
    baseQuery = baseQuery.Where(x=>x.ServiceId == filterServiceId); 
}

if(filterServiceId.hasValue){
    baseQuery = baseQuery.Where(x=>x.BrandId == filterBrandId); 
}

var results = baseQuery.Select(x=>x.Partner)
                       .ToList();

TODO:添加一个组,以便没有重复的合作伙伴。适应决赛&#34;选择&#34;获得所需的额外信息。

答案 1 :(得分:0)

改变你的逻辑。

if (search.ServiceId == 0)
{
    return new Partner[] {};
}

if (search.BrandId == 0)
{
    return new Partner[] {};
}

if (search.TrailerService != true)
{
    return new Partner[] {};
}

return dbContext.Partners
    .Where(p => p.PartnerServiceBrands
                 .Select(psb => psb.Service.Id)
                 .Contains(search.ServiceId))
    .Where(p => p.PartnerServiceBrands
                 .Select(psb => psb.Brand.Id)
                 .Contains(search.BrandId))
    .Where(x => x.PartnerServiceBrands
                 .Any(y => y.TrailerService == true));