如何在Entity Framework中编写参数化的where-in原始sql查询?我尝试了以下方法:
string dateQueryString = String.Join(",", chartModelData.GetFormattedDateList()); //Dates returned in format of 20140402,20140506,20140704 const string selectQuery = @"SELECT MAX(DATA_SEQ) AS MaxSeq, MIN(DATA_SEQ) AS MinSeq, COUNT(1) AS TotSampleCnt FROM SPCDATA_TB WHERE DATA_WDATE IN @DateParam AND LINE_CODE = @LineCode AND MODEL_NO = @ModelNumber AND LOT_NO = @LotNumber AND EQUIP_NO LIKE @EquipNumber"; SPCDataSeqCntInfo dataSeqCntInfo = _dbContext.Database.SqlQuery<SPCDataSeqCntInfo>( selectQuery, new SqlParameter("@DateParam", dateQueryString), new SqlParameter("@LineCode", chartModelData.LineCode), new SqlParameter("@ModelNumber", chartModelData.ModelNum), new SqlParameter("@EquipNumber", equipmentNumber), new SqlParameter("@LotNumber", chartModelData.LotNum) ).SingleOrDefault() ?? new SPCDataSeqCntInfo();
但是正如预期的那样,它在DateParam上引发错误,因为它期望一个值。
这不是实体框架特有的问题,您可以通过动态生成自己的参数名称来解决。
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());
发送到SQL-Server的结果查询如下所示:
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
通常,您希望避免在编写查询时进行字符串操作,但是,我相信此示例对于sql-injection是安全的。