【问题标题】:How to return null from a Dapper query rather than default(T)?如何从 Dapper 查询返回 null 而不是 default(T)?
【发布时间】:2012-07-30 11:29:24
【问题描述】:

我正在使用Dapper 通过存储过程进行一些只读数据库调用。我有一个查询,要么返回 1 行,要么什么都不返回。

我正在像这样使用 Dapper:

using (var conn = new SqlConnection(ConnectionString))
{
    conn.Open();

    return conn.Query<CaseOfficer>("API.GetCaseOfficer", 
        new { Reference = reference }, 
        commandType: CommandType.StoredProcedure).FirstOrDefault();
}

返回的 CaseOfficer 对象如下所示:

public class CaseOfficer
{
    public string Title { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Telephone { get; set; }
}

然后通过 ASP.NET Web API 应用程序将其作为 JSON 返回。

当存储过程返回结果时,我得到以下信息:

{
    title: "Mr",
    firstName: "Case",
    lastName: "Officer",
    email: "test@example.com",
    telephone: "01234 567890"
}

但是当它什么也没返回时,我得到:

{
    title: null,
    firstName: null,
    lastName: null,
    email: null,
    telephone: null
}

我怎样才能让 Dapper 返回 null(以便我可以检查并返回 404),而不是默认值(CaseOfficer)?

【问题讨论】:

  • 仅供参考,默认(CaseOfficer)为空。看起来它正在创建对象而不是填充字段。不能再帮你了,因为我不认识 Dapper

标签: c# stored-procedures null dapper


【解决方案1】:

如果你的 SP 没有返回一行,那么 dapper 就不会返回一行;所以首先要检查:你的 SP 是否可能返回一个空行?一行所有nulls ?还是返回 0 行?

现在,假设没有返回任何行,如果 CaseOfficerclassFirstOrDefault(标准 LINQ-to-Objects 事物)将返回 null,或者如果 CaseOfficer 是 @,则返回默认实例987654327@。所以接下来:检查CaseOfficerclass(我想不出任何理智的理由是struct)。

但是:带有FirstOrDefault 的小巧玲珑通常已经做了你想要的。

【讨论】:

  • SP 从外观上返回一行nulls。 CaseOfficer 是一个类。看看我是否可以修改存储过程以返回 0 行。
  • @James 另一种选择是找到一个必须具有值的列,并对其进行测试,例如.FirstOrDefault(x =&gt; x.FirstName != null)
  • 当 T 是可空类型(例如int?)时,Dapper 是否也返回 null?
  • @MarcGravell,如果我们使用 Query 执行存储过程并且如果存储过程不返回任何行,则 Dapper 返回计数为 0 的 IEnumerable。如果没有返回行,我们如何获得 null存储过程?我不想用 0 条记录初始化我的列表。在这种情况下,我想将其设置为 null。
  • @Priya 在我看来,dapper 正在 正确 那里得到它......一个空网格不是空的 - 它只有零行;但是:如果这不是您想要的,只需检查它是否为零行,如果是:在您自己的代码中将其替换为null。在这种情况下,Dapper 没有相应的 API。如果这是单行方案,您可以使用 FirstOrDefault&lt;T&gt; / SingleOrDefault&lt;T&gt;,如果没有返回任何行,则对于任何引用类型 T 将返回 null
【解决方案2】:

您可以设置默认属性。

例如:

public class BaseEntity
{
    public BaseEntity()
    {
        if (GetType().IsSubclassOf(typeof(BaseEntity)))
        {
            var properties = GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

            foreach (var property in properties)
            {
                // Get only string properties
                if (property.PropertyType != typeof (string))
                {
                    continue;
                }

                if (!property.CanWrite || !property.CanRead)
                {
                    continue;
                }

                if (property.GetGetMethod(false) == null)
                {
                    continue;
                }
                if (property.GetSetMethod(false) == null)
                {
                    continue;
                }

                if (string.IsNullOrEmpty((string) property.GetValue(this, null)))
                {
                    property.SetValue(this, string.Empty, null);
                }
            }
        }
    }
}

public class CaseOfficer : BaseEntity
{
    public string Title { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public string Telephone { get; set; }
}

现在,CaseOfficer 获得了自动属性

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    • 1970-01-01
    相关资源
    最近更新 更多