How do you write a parameterized where-in raw sql query in Entity Framework

后端 未结 3 1690
忘掉有多难
忘掉有多难 2020-12-15 05:30

How do you write a parameterized where-in raw sql query in Entity Framework? I\'ve tried the following:

string dateQueryString = String.Join(\",\", chartMode         


        
相关标签:
3条回答
  • 2020-12-15 06:15

    This isn't a problem specific to entity-framework, you can solve it by generating your own parameter names dynamically.

    var parameters = new List<SqlParameter> {
        new SqlParameter("@DateParam", dateQueryString),
        new SqlParameter("@LineCode", chartModelData.LineCode),
        new SqlParameter("@ModelNumber", chartModelData.ModelNum),
        new SqlParameter("@EquipNumber", equipmentNumber),
        new SqlParameter("@LotNumber", chartModelData.LotNum)   
    };
    
    var dateParameters = chartModelData
        .GetFormattedDateList()
        .Select((date, index) => new SqlParameter("@date" + index, date));
    
    parameters.AddRange(dateParameters);
    
    var inValues = string.Join(", ", dateParameters.Select(p => p.ParameterName));
    
    var query = @"SELECT MAX(DATA_SEQ) AS MaxSeq, 
       MIN(DATA_SEQ) AS MinSeq, 
       COUNT(1) AS TotSampleCnt
       FROM SPCDATA_TB
       WHERE DATA_WDATE IN (" + inValues + @")  
       AND LINE_CODE = @LineCode
       AND MODEL_NO = @ModelNumber
       AND LOT_NO = @LotNumber
       AND EQUIP_NO LIKE @EquipNumber";
    
    var myResult = _dbContext.Database
        .SqlQuery<SPCDataSeqCntInfo>(query, parameters.ToArray());
    

    The resulting query sent to SQL-Server will look like the following:

    SELECT 
       MAX(DATA_SEQ) AS MaxSeq, 
       MIN(DATA_SEQ) AS MinSeq, 
       COUNT(1) AS TotSampleCnt
    FROM SPCDATA_TB
    WHERE DATA_WDATE IN (@date0, @date1, @date2)  
    AND LINE_CODE = @LineCode
    AND MODEL_NO = @ModelNumber
    AND LOT_NO = @LotNumber
    AND EQUIP_NO LIKE @EquipNumber
    

    Generally, you want to avoid doing string manipulation when writing queries, however, I believe this example is safe from sql-injection.

    0 讨论(0)
  • 2020-12-15 06:16

    I'd write a stored proc instead which accepts your parameters, then add the proc to your edmx.

    Then, in the edmx -> Model Browser -> Function Imports -> ... change the return type of the stored proc to SPCDataSeqCntInfo.

    Entity framework will then take care of passing in your parameters.

    e.g.

    public static List<SPCDataSeqCntInfo> GetSPCDataSeqCntInfo(DateTime dateParam, string lineCode, int modelNum, int equipmentNumber, int lotNum)
    {
        using (var db = new NameOfMyEntites())
        {
            return db.sp_GetSPCDataSeqCntInfo(dateParam, lineCode, modelNum, equipmentNumber, lotNum).ToList();
        }
    }
    
    0 讨论(0)
  • 2020-12-15 06:30

    Here's how you would write your query in SQL.

    select *
        from MyTable
        where dateColumn in ('2014-01-01', '2014-02-01', '2014-03-01')
    

    So one shall not expect otherwise than having to represent this string entirely delimited by parenthesis.

    var dateQueryString = string.Join(",", chartModelData.GetFormattedDateList());
    // Dates shall be returned as DateTime.ToShortDateTimeString() as follows:
    // '2014-01-01', '2014-02-01', '2014-03-01'
    

    Then only remains to wrap it in parenthesis.

    var sql = @"select max(data_seq)    as MaxSeq
                        , min(data_seq) as MinSeq
                        , count(1)      as TotSampleCnt
                    from spcdata_tb
                    where data_wadate in (@DateParam)
                        and line_code  =  @LineCode
                        and model_no   =  @ModelNumber
                        and lot_no     =  @LotNumber
                        and equip_no like @EquipNumber";
    

    Provide the parameters values for each named parameter, and voilà! This shall do it!

    0 讨论(0)
提交回复
热议问题