使用Dapper查询复杂对象

15

我有一个Customer类,具有以下属性:

public int Id { get; set; }
public string Name { get; set; }
public int AddressId { get; set; }
public Address Address { get; set; }

我的目标是编写一个Dapper查询,使用内连接填充返回的每个客户的整个地址属性。

以下是我已经拥有并且有效运行,但我想知道这是否是最简洁/简单的方法:

StringBuilder sql = new StringBuilder();
using (var conn = GetOpenConnection())
{
    sql.AppendLine("SELECT c.Id, c.Name, c.AddressId, a.Address1, a.Address2, a.City, a.State, a.ZipCode ");
    sql.AppendLine("FROM Customer c ");
    sql.AppendLine("INNER JOIN Address a ON c.AddressId = a.Id ");

    return conn.Query<Customer, Address, Customer>(
        sql.ToString(),
        (customer, address) => {
            customer.Address= address;
            return userRole;
        },
        splitOn: "AddressId"
    ).ToList();
}

我对添加另一个属性有一些顾虑,比如:

public Contact Contact { get; set; }

我不确定如何更改上述语法以填充地址和联系人。


关键是让拆分的列具有相同的名称(例如 Id),然后只需使用 Query<Customer, Address, Contact, Customer> 即可。 - juharr
2个回答

15

我使用的是Dapper 1.40版本进行编码,我编写的查询方式如下,我没有遇到任何问题来填充多个对象,但我面临一个限制,即我只能在一个查询中映射最多8个不同的类。

public class Customer {
    public int Id { get; set; }
    public string Name { get; set; }
    public int AddressId { get; set; }  
    public int ContactId { get; set; }
    public Address Address { get; set; }
    public Contact Contact { get; set; }
}

public class Address {
    public int Id { get; set; }
    public string Address1 {get;set;}
    public string Address2 {get;set;}
    public string City {get;set;}
    public string State {get;set;}
    public int ZipCode {get;set;}
    public IEnumerable<Customer> Customer {get;set;}
}

public class Contact {
    public int Id { get; set; }
    public string Name { get; set; }
    public IEnumerable<Customer> Customer {get;set;}
}

using (var conn = GetOpenConnection())
{
    var query = _contextDapper
        .Query<Customer, Address, Contact, Customer>($@"
            SELECT c.Id, c.Name, 
                c.AddressId, a.Id, a.Address1, a.Address2, a.City, a.State, a.ZipCode,
                c.ContactId, ct.Id, ct.Name
            FROM Customer c
            INNER JOIN Address a ON a.Id = c.AddressId
            INNER JOIN Contact ct ON ct.Id = c.ContactId", 
            (c, a, ct) =>
            {
                c.LogType = a;
                c.Contact = ct;
                return c; 
            }, splitOn: "AddressId, ContactId")
        .AsQueryable();

    return query.ToList();          
}

2
{btsdaf} - Thiago Loureiro
11
我猜代码中的“c.LogType = a;”应该改为“c.Address = a;”。 - Daniel Silva

8

请看下面我用一个大查询的例子,注意每个查询行都是不同的对象。

public List<Appointment> GetList(int id)
{
    List<Appointment> ret;
    using (var db = new SqlConnection(connstring))
    {
        const string sql = @"SELECT AP.[Id], AP.Diagnostics, AP.Sintomns, AP.Prescription, AP.DoctorReport, AP.AddressId,
        AD.Id, AD.Street, AD.City, AD.State, AD.Country, AD.ZIP, Ad.Complement,
        D.Id, D.Bio, d.CRMNumber, D.CRMNumber, D.CRMState,
        P.Id,
        S.Id, S.Name,
        MR.Id, MR.Alergies, MR.BloodType, MR.DtRegister, Mr.HealthyProblems, MR.HealthyProblems, MR.Height, MR.MedicalInsuranceNumber, MR.MedicalInsuranceUserName, MR.Medications, MR.Weight,
        MI.Id, MI.Name
        from Appointment AP
        inner join [Address] AD on AD.Id = AP.AddressId
        inner join Doctor D on D.Id = AP.DoctorId
        inner join Patient P on P.Id = AP.PatientId
        left join Speciality S on S.Id = D.IDEspeciality
        left join MedicalRecord MR on MR.Id = P.MedicalRecordId
        left join MedicalInsurance MI on MI.Id = MR.MedicalInsuranceId
        where AP.Id = @Id
        order by AP.Id desc";

        ret = db.Query<Appointment, Address, Doctor, Patient, Speciality, MedicalRecord, MedicalInsurance, Appointment>(sql,
            (appointment, address, doctor, patient, speciality, medicalrecord, medicalinsurance) =>
            {
                appointment.Address = address;
                appointment.Doctor = doctor;
                appointment.Patient = patient;
                appointment.Doctor.Speciality = speciality;
                appointment.Patient.MedicalRecord = medicalrecord;
                appointment.Patient.MedicalRecord.MedicalInsurance = medicalinsurance;
                return appointment;
            }, new { Id = id }, splitOn: "Id, Id, Id, Id, Id, Id").ToList();
    }
    return ret;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接