Dapper - 使用除 Id 之外的分割点的多重映射

发布于 2024-12-10 17:54:32 字数 3818 浏览 0 评论 0原文

我知道这类似于 正确使用 Dapper 中的多重映射,但我认为略有不同。

我有以下 POCO 结构:

public class Customer
{
    public int customerkey { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string EmailAddress { get; set; }
    public List<Invoice> Invoices { get; set; }
    public int statekey { get; set; }
    public State State { get; set; }

    public Customer()
    {
        this.Invoices = new List<Invoice>();
    }
}

public class Invoice
{
    public int customerinvoicekey { get; set; }
    public int customerkey { get; set; }
    public int Number { get; set; }
    public string Description { get; set; }
    public int Total { get; set; }
    public int statuskey { get; set; }
    public State State { get; set; }
}

public class State
{   
    public int statekey { get; set; }
    public string Description { get; set; }
}

我正在尝试使用 Dapper 来映射它,并且我没有使用 Id 作为分割点。如果我将密钥加倍,我就可以让它工作,但我不确定为什么我必须这样做。

为什么这有效:

const string commandText =
        @"SELECT 
        A.customerkey, A.FirstName, A.LastName, A.EmailAddress, A.statuskey,
        C.statuskey, C.Description,
        B.customerinvoicekey, B.customerkey, B.Number, B.Description, B.Total, B.statuskey,
        D.statuskey, D.Description
        FROM Web.TestCustomers2 A
        INNER JOIN Web.TestCustomerInvoices2 B ON A.customerkey = B.customerkey
        INNER JOIN Web.TestStatus2 C ON A.statuskey = C.statuskey
        INNER JOIN Web.TestStatus2 D ON B.statuskey = D.statuskey
        ORDER BY A.customerkey";

        var customers = new List<Customer>();
        Customer currentCustomer = null;
        db.Connection.Query<Customer, State, Invoice, State, Customer>(commandText,
            (customer, customerstate, invoice, invoicestate) =>
            {
                if (currentCustomer == null || currentCustomer.customerkey != customer.customerkey)
                {
                    customers.Add(customer);
                    currentCustomer = customer;
                }
                invoice.State = invoicestate;
                currentCustomer.Invoices.Add(invoice);
                currentCustomer.State = customerstate;
                return currentCustomer;
            }, splitOn: "statuskey,customerinvoicekey,statuskey");

但这不起作用(忽略 A 和 B 中 statuskey 的选择):

const string commandText =
        @"SELECT 
        A.customerkey, A.FirstName, A.LastName, A.EmailAddress,
        C.statuskey, C.Description,
        B.customerinvoicekey, B.customerkey, B.Number, B.Description, B.Total,
        D.statuskey, D.Description
        FROM Web.TestCustomers2 A
        INNER JOIN Web.TestCustomerInvoices2 B ON A.customerkey = B.customerkey
        INNER JOIN Web.TestStatus2 C ON A.statuskey = C.statuskey
        INNER JOIN Web.TestStatus2 D ON B.statuskey = D.statuskey
        ORDER BY A.customerkey";

        var customers = new List<Customer>();
        Customer currentCustomer = null;
        db.Connection.Query<Customer, State, Invoice, State, Customer>(commandText,
            (customer, customerstate, invoice, invoicestate) =>
            {
                if (currentCustomer == null || currentCustomer.customerkey != customer.customerkey)
                {
                    customers.Add(customer);
                    currentCustomer = customer;
                }
                invoice.State = invoicestate;
                currentCustomer.Invoices.Add(invoice);
                currentCustomer.State = customerstate;
                return currentCustomer;
            }, splitOn: "statuskey,customerinvoicekey,statuskey");

I know this is similar to Correct use of Multimapping in Dapper, but I think it's slightly different.

I have the following POCO structure:

public class Customer
{
    public int customerkey { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string EmailAddress { get; set; }
    public List<Invoice> Invoices { get; set; }
    public int statekey { get; set; }
    public State State { get; set; }

    public Customer()
    {
        this.Invoices = new List<Invoice>();
    }
}

public class Invoice
{
    public int customerinvoicekey { get; set; }
    public int customerkey { get; set; }
    public int Number { get; set; }
    public string Description { get; set; }
    public int Total { get; set; }
    public int statuskey { get; set; }
    public State State { get; set; }
}

public class State
{   
    public int statekey { get; set; }
    public string Description { get; set; }
}

I am trying to map this using Dapper and I'm not using Id for my split points. I can get it to work if I double up the keys, but I'm not sure why I have to do that.

Why does this work:

const string commandText =
        @"SELECT 
        A.customerkey, A.FirstName, A.LastName, A.EmailAddress, A.statuskey,
        C.statuskey, C.Description,
        B.customerinvoicekey, B.customerkey, B.Number, B.Description, B.Total, B.statuskey,
        D.statuskey, D.Description
        FROM Web.TestCustomers2 A
        INNER JOIN Web.TestCustomerInvoices2 B ON A.customerkey = B.customerkey
        INNER JOIN Web.TestStatus2 C ON A.statuskey = C.statuskey
        INNER JOIN Web.TestStatus2 D ON B.statuskey = D.statuskey
        ORDER BY A.customerkey";

        var customers = new List<Customer>();
        Customer currentCustomer = null;
        db.Connection.Query<Customer, State, Invoice, State, Customer>(commandText,
            (customer, customerstate, invoice, invoicestate) =>
            {
                if (currentCustomer == null || currentCustomer.customerkey != customer.customerkey)
                {
                    customers.Add(customer);
                    currentCustomer = customer;
                }
                invoice.State = invoicestate;
                currentCustomer.Invoices.Add(invoice);
                currentCustomer.State = customerstate;
                return currentCustomer;
            }, splitOn: "statuskey,customerinvoicekey,statuskey");

But this does not work (leaving out the select of statuskey in A and B):

const string commandText =
        @"SELECT 
        A.customerkey, A.FirstName, A.LastName, A.EmailAddress,
        C.statuskey, C.Description,
        B.customerinvoicekey, B.customerkey, B.Number, B.Description, B.Total,
        D.statuskey, D.Description
        FROM Web.TestCustomers2 A
        INNER JOIN Web.TestCustomerInvoices2 B ON A.customerkey = B.customerkey
        INNER JOIN Web.TestStatus2 C ON A.statuskey = C.statuskey
        INNER JOIN Web.TestStatus2 D ON B.statuskey = D.statuskey
        ORDER BY A.customerkey";

        var customers = new List<Customer>();
        Customer currentCustomer = null;
        db.Connection.Query<Customer, State, Invoice, State, Customer>(commandText,
            (customer, customerstate, invoice, invoicestate) =>
            {
                if (currentCustomer == null || currentCustomer.customerkey != customer.customerkey)
                {
                    customers.Add(customer);
                    currentCustomer = customer;
                }
                invoice.State = invoicestate;
                currentCustomer.Invoices.Add(invoice);
                currentCustomer.State = customerstate;
                return currentCustomer;
            }, splitOn: "statuskey,customerinvoicekey,statuskey");

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

半仙 2024-12-17 17:54:32

customerinvoicekey 到底来自哪里?

您的模型声称该表的键是 public int customerkey { get;放; }。

如果您在模型中不存在的列上进行拆分,则多重映射函数的行为是未定义的。

Where exactly customerinvoicekey coming from?

Your model claims the key for the table is public int customerkey { get; set; }.

If you split on a column that is not in your models the behaviour of the multi-mapping functions is undefined.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文