DapperLib / DapperLib/Dapper

Mapping does not work properly

Open
#1,765 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
C#
Stars
18.4k
Forks
3.7k
Avg merge
5h 8m
Merged PRs (30d)
1

Description

I found this strange behaviour when mapping with dapper. Consider this example:

SELECT 
*
FROM `order` o
INNER JOIN `order_product` op ON op.order_id = o.order_id
WHERE o.order_id = 5153

I map this query using C# in the following way:

Dictionary<int, Order> orders = new Dictionary<int, Order>();

            var tmp = await connection.QueryAsync<Order, OrderProduct, Order>(@"SELECT 
*
FROM `order` o
INNER JOIN `order_product` op ON op.order_id = o.order_id
WHERE o.order_id = 5153", (order, product) =>
            {

                //person
                Order orderEntity;
                //trip
                if (!orders.TryGetValue(order.order_id, out orderEntity))
                {
                    orders.Add(order.order_id, orderEntity = order);
                }


                // Products
                if (orderEntity.Products == null)
                {
                    orderEntity.Products = new List<OrderProduct>();
                }

                if (product != null)
                {
                    if (!orderEntity.Products.Any(x => x.order_product_id == product.order_product_id))
                    {
                        orderEntity.Products.Add(product);
                    }
                }

                return orderEntity;
            }, splitOn: "order_id");

As you can see I'm selection all from both tables. However the property order_product_id is always 0.

When I run this query instead:
var products = await connection.QueryAsync<OrderProduct>("SELECT * FROM order_product where order_id = 5153");

I will get the order_product_id.

When I change the SQL from my main query to select this:
o.*, op.*, op.order_product_id

The order_product_id property will be set. But only if I select it as above.

The class for OrderProduct is a 1:1 representation of the DB.

public class OrderProduct
    {
        public int order_product_id { get; set; }
        public int order_id { get; set; }
        public int product_id { get; set; }
        public string name { get; set; }
        public string model { get; set; }
        public int quantity { get; set; }
        public decimal price { get; set; }
        public decimal total { get; set; }
        public decimal tax { get; set; }
        public int reward { get; set; }
    }

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the QueryAsync<Order, OrderProduct, Order> multi-mapping call and its splitOn: "order_id" argument. Compare the SELECT * query with the explicit o., op., op.order_product_id projection and trace how the returned columns map to OrderProduct. Done means the reported mapping behavior is understood and covered by an appropriate regression test.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp, sql
Domain
backend, databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.