2

实际上,我有一个查询,它返回包含 varchar 类型的列(例如地址)的结果,但该表的域模型包含对象类型的属性(例如地址地址)。因此它会引发错误,说无法转换字符串到评论。我不知道如何用 dapper .net 解决这个问题。

代码片段:

IEnumerable<Account> resultList = conn.Query<Account>(@"
                    SELECT * 
                    FROM Account
                    WHERE shopId = @ShopId", 
new {  ShopId = shopId });

以 Account 对象为例。

public class Account {
  public int? Id {get;set;}
  public string Name {get;set;}
  public Address Address {get;set;}
  public string Country {get;set;}
  public int ShopId {get; set;}
}

由于数据库表列(地址)和域模型属性(地址)之间存在类型不匹配,dapper 抛出异常。所以有什么方法可以通过 dapper 映射这些属性。

4

2 回答 2

4

另一种选择是使用 Dapper 的多重映射功能。

public class TheAccount
{
    public int? Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }
    public string Country { get; set; }
    public int ShopId { get; set; }
}

public class Address
{
    public string Street { get; set; }
    public string City { get; set; }
}

public class Class1
{
    [Test]
    public void MultiMappingTest()
    {
        var conn =
            new SqlConnection(
                @"Data Source=.\SQLEXPRESS; Integrated Security=true; Initial Catalog=MyDb");
        conn.Open();

        const string sql = "select Id = 1, Name = 'John Doe', Country = 'USA', ShopId = 99, " +
                           " Street = '123 Elm Street', City = 'Gotham'";

        var result = conn.Query<TheAccount, Address, TheAccount>(sql, 
            (account, address) =>
                {
                    account.Address = address;
                    return account;
                }, splitOn: "Street").First();

        Assert.That(result.Address.Street, Is.Not.Null);
        Assert.That(result.Country, Is.Not.Null);
        Assert.That(result.Name, Is.Not.Null);
    }
}

我看到的唯一问题是,您必须列出所有 Account 字段,然后是 select 语句中的 Address 字段,以允许 splitOn 工作。

于 2013-07-10T15:56:54.547 回答
1

由于 POCO 和数据库之间存在类型不匹配,因此您需要提供两者之间的映射。

public class Account {
  public int? Id {get;set;}
  public string Name {get;set;}
  public string DBAddress {get;set;}
  public Address Address 
  {
   // Propbably optimize here to only create it once.
   get { return new Address(this.DBAddress); } 
  }

  public string Country {get;set;}
  public int ShopId {get; set;}
}

类似的东西 - 您将 db 列与属性匹配DBAddress(您需要提供一个别名SELECT Address as DBAddress而不是 *)并在您的Address对象上提供一个 get 方法,该方法创建/重用Address带有 db 值内容的类型。

于 2013-07-10T10:37:11.343 回答