Dapper - custom mapping processing for a ddd object with read-only fields through the constructor

I have the following class that I am trying to moisten:

public class Product
{
    public readonly Sku Sku;
    public string Name { get; private set; }
    public string Description { get; private set; }
    public bool IsArchived { get; private set; }

    public Product(Sku sku, string name, string description, bool isArchived)
    {
        Sku = sku;
        Name = name;
        Description = description;
        IsArchived = isArchived;
    }
}

Which uses the classes below that implement the concepts from my DDD entity domain model (non-business code removed to keep the code short is set to readonly to make it immutable after it's created):

public class Sku
{
    public readonly VendorId VendorId;
    public readonly string SkuValue;

    public Sku(VendorId vendorId, string skuValue)
    {
        VendorId = vendorId;
        SkuValue = skuValue;
    }
}

public class VendorId
{
    public readonly string VendorShortname;

    public VendorId(string vendorShortname)
    {
        VendorShortname = vendorShortname;
    }
}

I am trying to run a parameterized query that will hydrate into a Product object:

using (connection)
{
    connection.Open();
    return connection.QueryFirst<Product>(ReadQuery, new { VendorId = sku.VendorId.VendorShortname, SkuValue = sku.SkuValue });
}

It throws the following exception because it does not know how to handle the type Skuin the constructor:

System.InvalidOperationException: ' (System.String VendorId, System.String SkuValue, System.String, System.String , System.UInt64 IsArchived) Domain.Model.Products.Product '

SqlMapper.TypeHandler<Product>, Parse(object value) - VendorId ( , ).

, , :

using (connection)
{
    var command = connection.CreateCommand();
    command.CommandText = "SELECT VendorShortname, SkuValue, Name, Description, IsArchived FROM Products WHERE VendorShortname=@VendorShortname AND SkuValue=@SkuValue";
    command.Parameters.AddWithValue("@VendorShortname", sku.VendorId.VendorShortname);
    command.Parameters.AddWithValue("@SkuValue", sku.SkuValue);
    connection.Open();

    var reader = command.ExecuteReader();
    if (reader.HasRows==false)
        return null;

    reader.Read();

    return new Product(
        new Sku(new VendorId(reader.GetString("VendorId")),reader.GetString("SkuValue")),
        reader.GetString("Name"),
        reader.GetString("Description"),
        reader.GetBoolean("IsArchived"));
}

, Product(string VendorShortname, string SkuValue, string Name, string Description, UInt64 IsArchived), () , .

, , ORM, Dapper.

  • ,
  • ( ) ( ) SQL

VendorShortname, VendorId(string vendorShortname), Name, Description, isArchived, Product(Sku sku, string name, string description, bool isArchived)... - MongoDB , , Dapper MongoDB Composite Key: InvalidOperationException: {document}.Identity

+4
2

public static IEnumerable<dynamic> Query (
    this IDbConnection cnn, 
    string sql, 
    object param = null, 
    SqlTransaction transaction = null, 
    bool buffered = true
)

, .

, , ...

using (connection)
{
    var command = connection.CreateCommand();
    command.CommandText = "SELECT VendorShortname, SkuValue, Name, Description, IsArchived FROM Products WHERE VendorShortname=@VendorShortname AND SkuValue=@SkuValue";
    command.Parameters.AddWithValue("@VendorShortname", sku.VendorId.VendorShortname);
    command.Parameters.AddWithValue("@SkuValue", sku.SkuValue);
    connection.Open();

    var reader = command.ExecuteReader();
    if (reader.HasRows==false)
        return null;

    reader.Read();

    return new Product(
        new Sku(new VendorId(reader.GetString("VendorId")),reader.GetString("SkuValue")),
        reader.GetString("Name"),
        reader.GetString("Description"),
        reader.GetBoolean("IsArchived"));
}

...

var ReadQuery = "SELECT VendorShortname, SkuValue, Name, Description, IsArchived FROM Products WHERE VendorShortname=@VendorShortname AND SkuValue=@SkuValue";
using (connection) {
    connection.Open();
    return connection.Query(ReadQuery, new { VendorShortname = sku.VendorId.VendorShortname, SkuValue = sku.SkuValue })
            .Select(row => new Product(
                new Sku(new VendorId(row.VendorShortname), row.SkuValue),
                row.Name,
                row.Description,
                row.IsArchived)
            );
}

. , , .

, , .

+3

"" . :

  • : ProductRecord
  • factory: ProductFactory
  • : var productRecords = connection.Query<ProductRecord>("select * from products").AsList();
  • : factory.Build(productRecords)

: , ,

: ,

+1

Source: https://habr.com/ru/post/1683589/


All Articles