8

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

我的 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 中编写这些查询,以返回我过滤字段的记录吗?

4

3 回答 3

5

使用 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 提供程序将Where在转换为 SQL 时对所有条件进行分组

于 2013-05-20T12:26:51.127 回答
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();
                    }
          }
于 2013-05-20T12:08:17.267 回答
1

您的示例非常复杂,但本质上您正在使用 linq 构建查询。

var someIQueryableInProgress = ... ;

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

然后评估您的所有条件何时适用,并让提供商为您完成工作。

于 2013-05-20T13:28:46.160 回答