将查询<t,.. =“”>扩展为7种以上</t,>

时间:2014-09-10 09:12:44

标签: c# sql generics mapping dapper

我正在使用Dapper来获取结果列表。我有很多&#34;值&#34; -tables只包含ID和名称。

我有这个SQL;

SELECT 
    MedicationScheduleItem.*,
    MedicationSchedule.*,
    Patient.*,
    Medication.*,
    MedicationBrand.*,
    MedicationScheduleItemRepeat.*,
    MedicationType.*,
    Measure.*

FROM MedicationScheduleItem
JOIN MedicationSchedule ON (MedicationSchedule.Id = MedicationScheduleItem.MedicationScheduleId)
JOIN Patient ON (Patient.Id = MedicationSchedule.PatientId)
JOIN Medication ON (Medication.Id = MedicationScheduleItem.MedicationId)
JOIN MedicationBrand ON (MedicationBrand.Id = Medication.MedicationBrandId)
JOIN MedicationType ON (MedicationType.Id = Medication.MedicationTypeId)
JOIN Measure ON (Measure.Id = Medication.MeasureId)
LEFT JOIN MedicationScheduleItemRepeat ON (MedicationScheduleItemRepeat.MedicationScheduleItemId = MedicationScheduleItem.Id)

我试图将SQL映射到这样的模型;

using Dapper;

//... 

private readonly IDbConnection _connection;

//... 

private IEnumerable<MedicationScheduleResultModel> QueryMedicationScheduleResultModels(string sql, object parameters = null)
{
    var results = new Dictionary<int, MedicationScheduleResultModel>();

    _connection.Query<MedicationScheduleItem, MedicationSchedule, Patient, Medication, MedicationBrand, MedicationScheduleItemRepeat, MedicationType, Measure, MedicationScheduleResultModel>(sql,
                (medicationScheduleItem, medicationSchedule, patient, medication, medicationBrand, medicationScheduleItemRepeat, medicationType, measure) =>
                {
                    MedicationScheduleResultModel viewModel;
                    if (!results.TryGetValue(medicationSchedule.Id, out viewModel))
                    {
                        results.Add(medicationSchedule.Id, new MedicationScheduleResultModel
                        {
                            Id = medicationSchedule.Id,
                            Patient = patient,
                            TimeCreated = medicationSchedule.TimeCreated,
                            StartDate = medicationSchedule.StartDate,
                            Schedules = new List<MedicationScheduleItemResultModel>()
                            {
                                BuildMedicationScheduleItemResultModel(medicationScheduleItem,
                                    medicationScheduleItemRepeat, medication, medicationBrand, medicationType, measure)
                            }
                        });
                    }
                    else
                    {
                        viewModel.Schedules.Add(BuildMedicationScheduleItemResultModel(medicationScheduleItem,
                            medicationScheduleItemRepeat, medication, medicationBrand));
                    }

                    return viewModel;
                }, parameters, splitOn: "Id, MedicationScheduleItemId");

    return results.Values;
}

private static MedicationScheduleItemResultModel BuildMedicationScheduleItemResultModel(MedicationScheduleItem medicationScheduleItem, MedicationScheduleItemRepeat medicationScheduleItemRepeat, Medication medication, MedicationBrand medicationBrand, MedicationType medicationType, Measure measure)
{
    return new MedicationScheduleItemResultModel()
    {
        Id = medicationScheduleItem.Id,
        ExecuteTime = medicationScheduleItem.ExecuteTime,
        RepeatTimeSpan = medicationScheduleItemRepeat != null
            ? (TimeSpan?)TimeSpan.FromTicks(medicationScheduleItemRepeat.RepeatTimeSpan)
            : null,
        Medication = new MedicationResultModel()
        {
            Id = medication.Id,
            Name = medication.Name,
            Brand = new MedicationBrand()
            {
                Id = medicationBrand.Id,
                Name = medicationBrand.Name
            },
            Measure = measure.Name,
            Type = medicationType.Name,
            Weight = medication.Weight
        }
    };
}

但是_connection.Query<T, ..>失败了,因为有许多泛型类型。

有没有办法让它发挥作用,或者我做错了吗?

1 个答案:

答案 0 :(得分:1)

您可以尝试直接映射到您感兴趣的最终类型,而不是将SQL结果映射到所有这些类型,而只是在初始化其他类型时使用它们。

所以不要这样:

_connection.Query<MedicationScheduleItem, MedicationSchedule, Patient, 
    Medication, MedicationBrand, MedicationScheduleItemRepeat, MedicationType,
    Measure, MedicationScheduleResultModel>(...

这可能足以构建您需要的对象图:

_connection.Query<MedicationScheduleResultModel, Patient, 
    MedicationScheduleItemResultModel, MedicationResultModel, MedicationBrand>(...

当然,这需要修改SELECT才能返回相应的字段。有点像...

SELECT
    -- columns that directly map to MedicationScheduleResultModel properties
    MedicationSchedule.id,
    MedicationSchedule.time_created TimeCreated, 
    MedicationSchedule.start_date StartDate,

    -- columns that directly map to Patient properties
    -- (to be used as MedicationScheduleResultModel.Patient)
    Patient.id, 
    Patient.name,

    -- columns that directly map to MedicationScheduleItemResultModel properties
    MedicationScheduleItem.id,
    MedicationScheduleItem.execute_time ExecuteTime,
    MedicationScheduleItemRepeat.repeat_time RepeatTime,

    -- columns that directly map to MedicationResultModel properties
    Medication.id,
    Medication.name,
    Measure.name,
    MedicationType.name,
    Medication.weight,

    -- columns that directly map to MedicationBrand properties
    MedicationBrand.id, 
    MedicationBrand.name
...

希望你明白这一点。

您甚至可以进一步扁平化,例如MedicationResultModel,以便它不包含复杂的MedicationBrand属性,而是包含MedicationBrandIdMedicationBrandName属性。但这取决于这是否适合您的其他设计。