SQL 到 LINQ(实体框架核心)

时间:2021-02-11 08:37:10

标签: entity-framework linq

我正在尝试将 SQL 写入 LINQ。我试过Linqpad,但是没有这个功能(只有LINQ to SQL转换)。

我有这个 SQL 查询

 SELECT
    count(*),
    count(TireWidth),
    count(TireRimDiameter),
    count(TireSeason),
    count(PriceCzk)
    FROM(
        SELECT 
            CASE WHEN TireWidth = 255 THEN 1 END TireWidth,
            CASE WHEN TireRimDiameter = 16 AND TireWidth = 255 THEN 1 END TireRimDiameter,
                CASE WHEN TireSeason = 1 THEN 1 END TireSeason,
            CASE WHEN PriceCzk > 50000 THEN 1 END PriceCzk
        FROM Products
        )
    Products

如何在 LINQ 中编写此查询?我正在使用 Entity Framework Core、.NET Core 5。

提前谢谢

2 个答案:

答案 0 :(得分:1)

诀窍在于通过常量使用 group by。 EF 将只创建简单的聚合查询。

var query = 
    from p in ctx.Products
    group p by 1 into g
    select new
    {
        Count = g.Count(),
        TireWidth = g.Sum(x => x.TireWidth == 255 ? 1 : 0),
        TireRimDiameter = g.Sum(x => x.TireRimDiameter == 16 && x.TireWidth == 255 ? 1 : 0),
        TireSeason = g.Sum(x => x.TireSeason == 1 ? 1 : 0),
        PriceCzk = g.Sum(x => x.PriceCzk > 50000 ? 1 : 0)
    };

答案 1 :(得分:0)

我没有找到 LINQ 解决方案,但此解决方案正在运行且速度非常快:

 var MySqlParameters = new List<MySqlParameter>();

            MySqlParameters.Add(new MySqlParameter("p_date", DateTime.UtcNow.Date));
            MySqlParameters.Add(new MySqlParameter("p_product_type", (int)(parameters.ProductType ?? 0)));
            MySqlParameters.AddRange(BuildInParameters("p_condition",
                parameters.Conditions.Select(c => (int)c), out var conditionParameters));
            MySqlParameters.AddRange(BuildInParameters("p_brand",
                parameters.Brands.Select(c => (int)c), out var brandParameters));
            MySqlParameters.AddRange(BuildInParameters("p_seller",
                parameters.UserTypes.Select(c => (int)c), out var sellerParameters));

            if (parameters.ToMileage != null)
                MySqlParameters.Add(new MySqlParameter("p_mileage", parameters.ToMileage));
            if (parameters.FromPrice != null)
                MySqlParameters.Add(new MySqlParameter("p_from_price", parameters.FromPrice));
            if (parameters.ToPrice != null)
                MySqlParameters.Add(new MySqlParameter("p_to_price", parameters.ToPrice));
            if (parameters.TireSeason != null)
                MySqlParameters.Add(new MySqlParameter("p_tire_ses", parameters.TireSeason));
            if (parameters.TireVehicleType != null)
                MySqlParameters.Add(new MySqlParameter("p_veh_type", parameters.TireVehicleType));
            if (parameters.TireWidth != null)
                MySqlParameters.Add(new MySqlParameter("p_tire_wid", parameters.TireWidth));
            if (parameters.TireHeight != null)
                MySqlParameters.Add(new MySqlParameter("p_tire_hei", parameters.TireHeight));
            if (parameters.TireRimDiameter != null)
                MySqlParameters.Add(new MySqlParameter("p_tire_rim", parameters.TireRimDiameter));
            if (parameters.TireLoadIndex != null)
                MySqlParameters.Add(new MySqlParameter("p_tire_loa", parameters.TireLoadIndex));
            if (parameters.TireSpeedRating != null)
                MySqlParameters.Add(new MySqlParameter("p_tire_spd", parameters.TireSpeedRating));
            if (parameters.FromYear != null)
                MySqlParameters.Add(new MySqlParameter("p_car_fromYear", parameters.FromYear));
            if (parameters.ToYear != null)
                MySqlParameters.Add(new MySqlParameter("p_car_toYear", parameters.ToYear));

            var builder = new StringBuilder();

                    if (isTireWidth)
                    {
                        builder.AppendLine($@"UNION ALL
    SELECT 'TireWidth' FilterName, TireWidth FilterValue, COUNT(1) as FilterCount FROM
    `products` P LEFT OUTER JOIN `aspnetusers` U ON P.UserId=U.Id 
     WHERE P.Deleted=0 AND TireWidth IS NOT NULL
     AND (P.ExpirationDateUtc='0001-01-01' OR P.ExpirationDateUtc >= @p_date)
     AND P.ProductType = @p_product_type");
                        if (conditionParameters != "") builder.AppendLine($"AND P.ProductCondition IN ({conditionParameters})");
                        if (brandParameters != "") builder.AppendLine($"AND P.Brand IN ({brandParameters})");
                        if (sellerParameters != "") builder.AppendLine($"AND U.Type IN ({sellerParameters})");
                        if (parameters.ToMileage != null) builder.AppendLine($"AND P.Mileage <= @p_mileage");
                        if (parameters.FromPrice != null) builder.AppendLine($"AND P.PriceCzk >= @p_from_price");
                        if (parameters.ToPrice != null) builder.AppendLine($"AND P.PriceCzk <= @p_to_price");
                        if (parameters.TireSeason != null) builder.AppendLine($"AND P.TireSeason = @p_tire_ses");
                        if (parameters.TireVehicleType != null) builder.AppendLine($"AND P.TireVehicleType = @p_veh_type");
                        //if (parameters.TireWidth != null) builder.AppendLine($"AND P.TireWidth = @p_tire_wid");
                        if (parameters.TireHeight != null) builder.AppendLine($"AND P.TireHeight = @p_tire_hei");
                        if (parameters.TireRimDiameter != null) builder.AppendLine($"AND P.TireRimDiameter = @p_tire_rim");
                        if (parameters.TireLoadIndex != null) builder.AppendLine($"AND P.TireLoadIndex = @p_tire_loa");
                        if (parameters.TireSpeedRating != null) builder.AppendLine($"AND P.TireSpeedRating = @p_tire_spd");
                        builder.AppendLine("GROUP BY TireWidth");
                    }
    
                    if (isTireVehicleType)
                    {
                        builder.AppendLine($@"UNION ALL
    SELECT 'TireVehicleType' FilterName, TireVehicleType FilterValue, COUNT(1) as FilterCount FROM
    `products` P LEFT OUTER JOIN `aspnetusers` U ON P.UserId=U.Id 
     WHERE P.Deleted=0 AND TireVehicleType IS NOT NULL
     AND (P.ExpirationDateUtc='0001-01-01' OR P.ExpirationDateUtc >= @p_date)
     AND P.ProductType = @p_product_type");
                        if (conditionParameters != "") builder.AppendLine($"AND P.ProductCondition IN ({conditionParameters})");
                        if (brandParameters != "") builder.AppendLine($"AND P.Brand IN ({brandParameters})");
                        if (sellerParameters != "") builder.AppendLine($"AND U.Type IN ({sellerParameters})");
                        if (parameters.ToMileage != null) builder.AppendLine($"AND P.Mileage <= @p_mileage");
                        if (parameters.FromPrice != null) builder.AppendLine($"AND P.PriceCzk >= @p_from_price");
                        if (parameters.ToPrice != null) builder.AppendLine($"AND P.PriceCzk <= @p_to_price");
                        if (parameters.TireSeason != null) builder.AppendLine($"AND P.TireSeason = @p_tire_ses");
                        //if (parameters.TireVehicleType != null) builder.AppendLine($"AND P.TireVehicleType = @p_veh_type");
                        if (parameters.TireWidth != null) builder.AppendLine($"AND P.TireWidth = @p_tire_wid");
                        if (parameters.TireHeight != null) builder.AppendLine($"AND P.TireHeight = @p_tire_hei");
                        if (parameters.TireRimDiameter != null) builder.AppendLine($"AND P.TireRimDiameter = @p_tire_rim");
                        if (parameters.TireLoadIndex != null) builder.AppendLine($"AND P.TireLoadIndex = @p_tire_loa");
                        if (parameters.TireSpeedRating != null) builder.AppendLine($"AND P.TireSpeedRating = @p_tire_spd");
                        builder.AppendLine("GROUP BY TireVehicleType");
                    }

   var result = _context.FilterQueries.FromSqlRaw(builder.ToString(), MySqlParameters.ToArray());
            return result;