使用 Dapper 将项目列表(可能为空)作为 IN 子句的参数传递
Passing in a list of items (that can possibly be null) as params for an IN clause using Dapper
尝试使用 Dapper 将 NULL 项目列表作为参数传递时,出现 NULL 引用异常。通常在我的 where 子句中,我会简单地执行以下操作:
"AND (@Sections IS NULL OR Section IN @Sections)";
但我无法执行此操作,因为即使部分列表中有项目,它也不会工作。 Dapper 将它们添加为参数并且 (@sections1,@sections2 IS NULL OR) 将出错。如果我将我的部分列表保留为空,因为我不想将它用作过滤器,我会得到一个 NULL 引用异常。
我的函数必须有一个部分列表作为可选参数。这样,在我的代码中,我不必总是向我的查询添加部分过滤器。如何在我的函数参数中使部分成为可为 null 的列表,同时在 NULL 时也能与 Dapper 一起工作?
这是我的代码:
public static IEnumerable<Product> GetProformaFormularies(int? categoryId = null, IEnumerable<int> sections = null)
{
using (var context = new AppContext())
{
var sql =
"SELECT * " +
"FROM Products " +
"WHERE (@CategoryId IS NULL OR CategoryId = @CategoryId) " +
"AND (Section IN @Sections)";
return context.Database.Connection.Query<Product>(sql,
new {
CategoryId = categoryId,
Sections = sections
}).ToList();
}
}
我想到的唯一解决方案是使用动态参数。还有比这更好的方法吗?
var sql =
"SELECT * " +
"FROM ProformaFormulary " +
"WHERE (@CategoryId IS NULL OR CategoryId = @CategoryId) " +
if (sections != null)
{
sql += " AND (Section IN @Sections)";
}
var parameters = new DynamicParameters();
parameters.Add("@CategoryId", categoryId);
if (sections != null)
{
parameters.Add("@Sections", sections);
}
如果 sections
是 null
,您可以省略 WHERE
子句的那部分:
var sql =
"SELECT * " +
"FROM Products " +
"WHERE (@CategoryId IS NULL OR CategoryId = @CategoryId) ";
if (sections != null)
{
sql += "AND (Section IN @Sections)"
}
return context.Database.Connection.Query<Product>(sql,
new {
CategoryId = categoryId,
Sections = sections
}).ToList();
如果不适用,dapper 似乎只会忽略您传递的对象上的 Sections
属性。
在我看来,代码中的 if 语句有时并不是您想要的。我有时只执行 .sql
个文件。所以唯一对我有用的就是这个。
var parameters = new
{
ApplySectionFilter = stringsToFilter != null,
Sections = stringsToFilter
};
有一点开销,但最终更干净。在我看来。
SELECT * FROM Products
WHERE (@ApplySectionFilter = 0 OR Section IN @Sections)
尝试使用 Dapper 将 NULL 项目列表作为参数传递时,出现 NULL 引用异常。通常在我的 where 子句中,我会简单地执行以下操作:
"AND (@Sections IS NULL OR Section IN @Sections)";
但我无法执行此操作,因为即使部分列表中有项目,它也不会工作。 Dapper 将它们添加为参数并且 (@sections1,@sections2 IS NULL OR) 将出错。如果我将我的部分列表保留为空,因为我不想将它用作过滤器,我会得到一个 NULL 引用异常。
我的函数必须有一个部分列表作为可选参数。这样,在我的代码中,我不必总是向我的查询添加部分过滤器。如何在我的函数参数中使部分成为可为 null 的列表,同时在 NULL 时也能与 Dapper 一起工作?
这是我的代码:
public static IEnumerable<Product> GetProformaFormularies(int? categoryId = null, IEnumerable<int> sections = null)
{
using (var context = new AppContext())
{
var sql =
"SELECT * " +
"FROM Products " +
"WHERE (@CategoryId IS NULL OR CategoryId = @CategoryId) " +
"AND (Section IN @Sections)";
return context.Database.Connection.Query<Product>(sql,
new {
CategoryId = categoryId,
Sections = sections
}).ToList();
}
}
我想到的唯一解决方案是使用动态参数。还有比这更好的方法吗?
var sql =
"SELECT * " +
"FROM ProformaFormulary " +
"WHERE (@CategoryId IS NULL OR CategoryId = @CategoryId) " +
if (sections != null)
{
sql += " AND (Section IN @Sections)";
}
var parameters = new DynamicParameters();
parameters.Add("@CategoryId", categoryId);
if (sections != null)
{
parameters.Add("@Sections", sections);
}
如果 sections
是 null
,您可以省略 WHERE
子句的那部分:
var sql =
"SELECT * " +
"FROM Products " +
"WHERE (@CategoryId IS NULL OR CategoryId = @CategoryId) ";
if (sections != null)
{
sql += "AND (Section IN @Sections)"
}
return context.Database.Connection.Query<Product>(sql,
new {
CategoryId = categoryId,
Sections = sections
}).ToList();
如果不适用,dapper 似乎只会忽略您传递的对象上的 Sections
属性。
在我看来,代码中的 if 语句有时并不是您想要的。我有时只执行 .sql
个文件。所以唯一对我有用的就是这个。
var parameters = new
{
ApplySectionFilter = stringsToFilter != null,
Sections = stringsToFilter
};
有一点开销,但最终更干净。在我看来。
SELECT * FROM Products
WHERE (@ApplySectionFilter = 0 OR Section IN @Sections)