使用Dapper

时间:2015-06-16 14:44:49

标签: c# sql sql-server sql-server-2008 dapper

尝试使用Dapper将项目的NULL列表作为参数传递时,我收到NULL引用异常。通常在我的where子句中,我会简单地执行以下操作:

"AND (@Sections IS NULL OR Section IN @Sections)";

但我无法做到这一点,因为即使部分列表中有项目,它也无法工作。 Dapper将它们作为参数添加(@ sections1,@ sections2 IS NULL OR)将错误输出。如果我将我的部分列表留空,因为我不想将它用作过滤器,我会得到一个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);
}

2 个答案:

答案 0 :(得分:4)

如果WHEREsections,您可以省略null子句的那一部分:

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属性。

答案 1 :(得分:0)

我认为代码中的if语句有时不是您想要的。有时我只执行.sql文件。因此,唯一对我有用的是这个。

var parameters = new
            {
                ApplySectionFilter = stringsToFilter != null,
                Sections = stringsToFilter 
            };

有一些开销,但是最后,它更干净。我认为。

SELECT * FROM Products
    WHERE (@ApplySectionFilter = 0 OR Section IN @Sections)