LINQ where子句中的三元运算符

时间:2013-05-20 11:57:44

标签: c# linq sql-server-2008

我使用linq连接多个表并编写复杂查询。这里当我将'0'作为任何参数,即CategoryIdGameIdLimitVariantId时,这意味着用户已从界面中选择“全部”。

我的Sql查询,当我将参数值传递给大于'0'时:

select * from dbo.GameCombinations gc
inner join dbo.StakeBuyInByStakeCategories sbsc
on sbsc.StakeBuyInByStakeCategoryId = gc.StakeBuyInByStakeCategoryId
inner join dbo.GameTables gt
on gc.GameCombinationId = gt.GameCombinationId
where gc.CurrencyId=1 and gc.GameTypeId=2
and sbsc.StakeBuyInId=gt.BuyIn
and gc.CategoryId=4
and gc.GameId=7
and gc.LimitVariantId=23
and gc.StakeCategoryId in (3,5,6)

当我将CategoryId作为0传递时,我的Sql查询将是:

select * from dbo.GameCombinations gc
inner join dbo.StakeBuyInByStakeCategories sbsc
on sbsc.StakeBuyInByStakeCategoryId = gc.StakeBuyInByStakeCategoryId
inner join dbo.GameTables gt
on gc.GameCombinationId = gt.GameCombinationId
where gc.CurrencyId=1 and gc.GameTypeId=2
and sbsc.StakeBuyInId=gt.BuyIn
--and gc.CategoryId=4
and gc.GameId=7
and gc.LimitVariantId=23
and gc.StakeCategoryId in (3,5,6)

所以我不需要在where子句中包含那些字段。为此我写了以下LINQ:

ProviderDB db = new ProviderDB();
try
{
    IQueryable<dynamic> query;

    if (StakeCategoryIdsByStakeBuyIn != null)
    {
        query = (from gc in db.GameCombinations.Where(x => x.CurrencyId == CurrencyId && x.GameTypeId == GameTypeId
                            && CategoryId <= 0 ? true : x.CategoryId == CategoryId
                            && GameId <= 0 ? true : x.GameId == GameId
                            && LimitVariantId <= 0 ? true : x.LimitVariantId == LimitVariantId
                            && StakeCategoryIdsByStakeBuyIn.Contains(x.StakeCategoryId)
                        )
                 join sbsc in db.StakeBuyInByStakeCategories
                 on gc.StakeBuyInByStakeCategoryId equals sbsc.StakeBuyInByStakeCategoryId
                 join gt in db.GameTables
                 on gc.GameCombinationId equals gt.GameCombinationId
                 join gx in db.Games
                 on gc.GameId equals gx.GameId into joined
                 from gx in joined.DefaultIfEmpty()
                 where gt.BuyIn == sbsc.StakeBuyInId
                 select new
                 {
                     GameTableId = gt.GameTableId,
                     Description = gt.Description,
                     BuyIn = gt.BuyIn,
                     Table = gx.GameName,
                     MaxAllowPlayer = gt.MaxAllowPlayer
                 }).Distinct();
    }
    else
    {
        query = (from gc in db.GameCombinations.Where(x => x.CurrencyId == CurrencyId && x.GameTypeId == GameTypeId
                              && CategoryId == 0 ? true : x.CategoryId == CategoryId
                              && GameId == 0 ? true : x.GameId == GameId
                              && LimitVariantId == 0 ? true : x.LimitVariantId == LimitVariantId
                              && StakeCategoryIdsByStakeBuyIn == null
                        )
                 join sbsc in db.StakeBuyInByStakeCategories
                 on gc.StakeBuyInByStakeCategoryId equals sbsc.StakeBuyInByStakeCategoryId
                 join gt in db.GameTables
                 on gc.GameCombinationId equals gt.GameCombinationId
                 join sb in db.StakeBuyIns
                 on gt.BuyIn equals sb.StakeBuyInId
                 join gx in db.Games
                 on gc.GameId equals gx.GameId into joined
                 from gx in joined.DefaultIfEmpty()
                 where gt.BuyIn == sbsc.StakeBuyInId
                 select new
                 {
                     GameTableId = gt.GameTableId,
                     Description = gt.Description,
                     BuyIn = sb.StakeBuyInValue,
                     Table = gx.GameName,
                     MaxAllowPlayer = gt.MaxAllowPlayer
                 }).Distinct();
    }

但这将返回我数据库中的所有字段。那么任何人都可以帮我在LINQ中用三元条件编写这些查询,这些条件会返回我过滤字段的记录吗?

3 个答案:

答案 0 :(得分:4)

使用Linq to SQL(通常使用LINQ),您可以通过编程方式添加Where条件,例如:

var query = db.GameCombinations.Where(x => x.CurrencyId == CurrencyId && x.GameTypeId == GameTypeId);

if (CategoryId > 0)
{
    query = query.Where(x => x.CategoryId == CategoryId);
}

等等。

此外,最好使用“类型推断”(使用var关键字)代替dynamic,您将无法使用dynamic

进行智能感知

<强> [编辑] Linq to SQL提供程序将在转换为SQL

时对所有Where条件进行分组

答案 1 :(得分:1)

您仍然可以在SQL中执行此查询,尝试类似:

select * from dbo.GameCombinations gc
inner join dbo.StakeBuyInByStakeCategories sbsc
on sbsc.StakeBuyInByStakeCategoryId = gc.StakeBuyInByStakeCategoryId
inner join dbo.GameTables gt
on gc.GameCombinationId = gt.GameCombinationId
where gc.CurrencyId=1 and gc.GameTypeId=2
and sbsc.StakeBuyInId=gt.BuyIn
and (0 = categoryParameter OR gc.CategoryId=categoryParameter) //Pass 0 to take all categories
and gc.GameId=7
and gc.LimitVariantId=23
and gc.StakeCategoryId in (3,5,6)

修改

对其余参数执行相同的操作:

ProviderDB db = new ProviderDB();

                try
                {
                    IQueryable<dynamic> query;

                    if (StakeCategoryIdsByStakeBuyIn != null)
                    {
                        query = (from gc in db.GameCombinations.Where(x => x.CurrencyId == CurrencyId && x.GameTypeId == GameTypeId
                                            && (CategoryId == 0 || x.CategoryId == CategoryId)
                                            && (GameId == 0 || x.GameId == GameId)
                                            && (LimitVariantId == 0 || x.LimitVariantId == LimitVariantId)
                                            && StakeCategoryIdsByStakeBuyIn.Contains(x.StakeCategoryId)
                                        )
                                 join sbsc in db.StakeBuyInByStakeCategories
                                 on gc.StakeBuyInByStakeCategoryId equals sbsc.StakeBuyInByStakeCategoryId
                                 join gt in db.GameTables
                                 on gc.GameCombinationId equals gt.GameCombinationId
                                 join gx in db.Games
                                 on gc.GameId equals gx.GameId into joined
                                 from gx in joined.DefaultIfEmpty()
                                 where gt.BuyIn == sbsc.StakeBuyInId
                                 select new
                                 {
                                     GameTableId = gt.GameTableId,
                                     Description = gt.Description,
                                     BuyIn = gt.BuyIn,
                                     Table = gx.GameName,
                                     MaxAllowPlayer = gt.MaxAllowPlayer
                                 }).Distinct();
                    }
          }

答案 2 :(得分:0)

您的示例非常复杂,但实际上您使用linq来构建查询。

var someIQueryableInProgress = ... ;

if (categoryId != 0)
{
    someIQueryableInProgress = someIQueryableInProgress
        .Where(s => s.categoryId = categoryId)
}

然后评估何时应用所有条件并让提供者为您完成工作。