Dapper .Net: colonne de table et incompatibilité de type de propriété de modèle

dapper

Question

En fait, j'ai une requête qui renvoie un résultat contenant une colonne (pour ex.Address) de type varchar mais le modèle de domaine pour cette table contenant la propriété de type object (par exemple Address Address). chaîne à Comment.Je n'arrive pas à comprendre comment résoudre ce problème avec dapper .net.

Extrait de code:

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

L'objet Compte est par exemple.

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;}
}

Comme il existe une incohérence de type entre la colonne de la table de base de données (Address) et la propriété du modèle de domaine (Address), dapper émet une exception.

Réponse acceptée

Comme il existe une incompatibilité de type entre votre POCO et votre base de données, vous devrez fournir un mappage entre les deux.

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;}
}

Quelque chose comme ça - vous faites correspondre la colonne db à la propriété DBAddress (vous devez fournir un alias comme SELECT Address as DBAddress au lieu de *) et fournir une méthode get sur votre objet Address qui crée / réutilise un type d' Address avec le contenu de la valeur db.


Réponse populaire

Une autre option consiste à utiliser la fonctionnalité Multi-Mapping de 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);
    }
}

Le seul problème que je vois avec ceci est que vous devrez lister tous les champs de compte, suivis des champs d'adresse dans votre instruction select, pour permettre à splitOn de fonctionner.




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi