public List<PostJobListModel> GetPostsByCompanyId(int id, int s, int d, int p)
{
string command = @"select Id,Title,Cities = STUFF(
(SELECT ',' + City.Name
FROM City where City.Id in (select Id from LocaitonJobRelationship as ljr where ljr.JobId = PostJob.Id)
FOR XML PATH ('')), 1, 1, ''),
Features = STUFF(
(SELECT ',' + Feature.Name
FROM Feature where Feature.Id in (select FeatureId from FeatureJobRelationship as fjr where fjr.JobId = PostJob.Id and (fjr.CategoryId in (@s,@d,@p) ) )FOR XML PATH('')), 1, 1, '')from PostJob where CompanyId = " + id + "";
SqlParameter parameterS = new SqlParameter("@s", s);
SqlParameter parameterD = new SqlParameter("@d", d);
SqlParameter parameterP = new SqlParameter("@p", p);
return _repositoryCustom.FromSql(command, s, d, p).ToList();
}
//存储库
public List<PostJobListModel> FromSql(string sql, params object[] objects)
{
return _context.PostJobListModel.FromSql(sql,objects).ToList();
}
此代码提供“SQLException必须声明标量变量”@variableName“” 我如何创建安全命令字符串?
答案 0 :(得分:8)
您不通过执行SqlCommand设置参数,您需要将参数传递给FromSql
语句。来自the documention
您还可以构建DbParameter并将其作为参数提供 值。这允许您在SQL查询中使用命名参数 串+
var user = new SqlParameter("user", "johndoe"); var blogs = context.Blogs .FromSql("EXECUTE dbo.GetMostPopularBlogsForUser @user", user) .ToList();
因此,对于您的代码,您可以
public List<PostJobListModel> GetPostsByCompanyId(int id, int s, int d, int p)
{
string command = @"select Id,Title,Cities = STUFF(
(SELECT ',' + City.Name
FROM City where City.Id in (select Id from LocaitonJobRelationship as ljr where ljr.JobId = PostJob.Id)
FOR XML PATH ('')), 1, 1, ''),
Features = STUFF(
(SELECT ',' + Feature.Name
FROM Feature where Feature.Id in (select FeatureId from FeatureJobRelationship as fjr where fjr.JobId = PostJob.Id and (fjr.CategoryId in (@s,@d,@p) ) )FOR XML PATH('')), 1, 1, '')from PostJob where CompanyId = " + id + "";
SqlParameter parameterS = new SqlParameter("@s", s);
SqlParameter parameterD = new SqlParameter("@d", d);
SqlParameter parameterP = new SqlParameter("@p", p);
return _repositoryCustom.FromSql(command, parameterS, parameterD, parameterP).ToList();
}
你也应该id
一个参数。
答案 1 :(得分:2)
当我通过EF Core调用SQL存储的proc时,我想构建一个SqlParameter数组,以帮助我使用FromSql调用中所需的参数将SQL捣碎,像这样:
using (var scope = _services.CreateScope())
{
var parameters = new []
{
new SqlParameter("param1", System.Data.SqlDbType.VarChar, 10) { Value = someInboundMethodParam },
new SqlParameter("param2", System.Data.SqlDbType.VarChar, 50) { Value = Environment.UserName },
// etc..
};
var sql = new System.Text.StringBuilder("exec YourStoreProc");
sql.Append(string.Join(separator: ",", values: parameters.Select(p => $" @{ p.ParameterName }")));
var ctx = scope.ServiceProvider.GetRequiredService<YourContext>();
return await ctx
.Query<SomeView>()
.AsNoTracking()
.FromSql(sql.ToString(), parameters.ToArray<object>())
.FirstOrDefaultAsync(cancellationToken);
}
在一些迭代中,我建立了以下内容来帮助编写SQL:
public static string GetStoredProcSql(string name, SqlParameter[] parameters)
{
var stringOfParameters =
string.Join(
separator: ",",
values: parameters.Select(GetStringOfParameterNameValuePairs)
);
return $"exec [{name}] {stringOfParameters};";
}
public static string GetStringOfParameterNameValuePairs(SqlParameter parameter)
{
var name = parameter.ParameterName;
var value =
ShouldSqlDbTypeValueRequireQuotes(parameter)
? $"\'{parameter.Value}\'"
: parameter.Value;
return $" @{name}={value}";
}
public static bool ShouldSqlDbTypeValueRequireQuotes(SqlParameter parameter)
{
return new Enum[] {
// SqlDbTypes that require their values be wrapped in single quotes:
SqlDbType.VarChar,
SqlDbType.NVarChar
}.Contains(parameter.SqlDbType);
}
要使用:
public async Task<List<JobView>> GetJobList(
CancellationToken cancellationToken,
int pageStart = 1,
int pageSize = 10
//List.ClaimFilter filter = null // future
)
{
using (var scope = _services.CreateScope())
{
var logger = scope.ServiceProvider.GetRequiredService<ILogger<ISomeService>>();
logger.LogInformation($"Getting list of share creation jobs..");
var ctxJob = scope.ServiceProvider.GetRequiredService<JobContext>();
var sql = SqlDataHelper.GetStoredProcSql( // use here!
"GetJobList",
new[]
{
new SqlParameter("pageStart", System.Data.SqlDbType.Int) { Value = pageStart },
new SqlParameter("pageSize", System.Data.SqlDbType.Int) { Value = pageSize },
//new SqlParameter("filterFieldValuePairs", System.Data.SqlDbType.VarChar) { Value = filter },
new SqlParameter("itemType", System.Data.SqlDbType.VarChar, 10) { Value = "Share" },
});
return await ctxJob
.Query<JobView>()
.AsNoTracking()
.FromSql(sql)
.ToListAsync(cancellationToken);
}
}
答案 2 :(得分:-1)
在.Net Core 2.0+中,以下代码为我工作。无需传递SQLParameter类。
public List<XXSearchResult> SearchXXArticles(string searchTerm,bool published=true,bool isXX=true)
{
var listXXArticles = _dbContext.XXSearchResults.FromSql($"SELECT * FROM [dbo].[udf_textContentSearch] ({searchTerm}, {published}, {isXX})").ToList();
return listXXArticles;
}
// XXSearchResult在DbContext类中声明为: 公共DbQuery XXSearchResults {get;组; }
// udf_textContentSearch是我在SQL Server数据库中的旧函数。 SELECT * FROM [dbo]。[udf_textContentSearch]