2015-04-13 4 views
3

У меня есть одна таблица, но я бы хотел отобразить ее как композицию между двумя классами.Состав Dapper.NET, используя ту же таблицу

Предположим, у меня есть таблица Customer со следующими полями: Id, Name, ExtraDataValue, ExtraDataDate.

class Customer 
{ 
    public int Id {get;set;} 
    public string Name {get;set;} 
    public ExtraData Extra {get;set;} 
} 

class ExtraData 
{ 
    public int Value {get;set;} 
    public DateTime Date {get;set;} 
} 

Каков наилучший способ запроса и заполнения ExtraData внутри объекта Customer?

Edit:

Я простираться вопрос к более сложному сценарию, так как ответ XenoPuTtSs в решает первый, но не будет работать с этим.

Предположим теперь, что у меня есть соединение, чтобы обратиться к таблице. Опция splitOn разделит результат на создание ExtraData, но не будет разделена на создание адреса.

Я вижу другую проблему, используя splitOn. Мы не можем использовать Select * безопасно, потому что, если мы изменяем таблицу с большим количеством полей, мы должны всегда помнить, чтобы перемещать поля сплита вниз. Или мы всегда будем описывать все поля в безопасном порядке в команде Select.

+0

Я согласен с тем, что вы говорите о «Select *», но, как правило, это плохая практика в любом месте по тем же причинам. splitOn используется, потому что ключ по умолчанию не является «Id» – XenoPuTtSs

+0

Но в этом случае мне действительно нужны все поля, поэтому Select * is perfect. Теперь я понимаю использование splitOn, но в этом случае проблема. Я хочу разбить имя поля (для ExtraData) и для ключа (для адресной таблицы). Может быть, если он примет список вариантов разделения, было бы лучше. Что-то вроде splitOn: new {"Id", "ExtraDataValue"} –

+1

splitOn: "Value1, ID, SomethingElse, Chickens" – XenoPuTtSs

ответ

1

splitOn: "Id, ExtraDataValue, Id" Я считаю, что это отвечает на вашу новейшую постановку вопроса. Теперь у вас есть соединение для адресации, и оно заполняет адресную часть объекта вашего клиента.

class Customer 
{ 
    public int Id {get;set;} 
    public int Name {get;set;} 
    public ExtraData Extra {get;set;} 
    public Address Address{get;set;} 
} 

class ExtraData 
{ 
    public int Value {get;set;} 
    public int Date {get;set;} 
} 

class Address { 
    public string line1{get;set;} 
} 

using (var conn = DatabaseService.CreateConnection()) 
{ 
    var t = conn.Query<Customer, ExtraData, Address, Customer>(@" 
    select 
     c.cust_num as Id, 
     c.cust_name as Name, 
     c.ex_data1 as Value, 
     c.ex_date as Date, 
     a.* 
    from Customer c 
    join Address a on c.addressid = a.addressid 
    ", 
    (cust, extra, address) => 
    { 
     cust.Extra = extra; 
     cust.Address = address; 
     return cust; 
    }, 
    splitOn:"Id, Value, Id"); 
    return t; 
} 
+0

Я тоже пробовал эту опцию, но она не работает. Я всегда получаю эту ошибку: «При использовании API-интерфейсов множественного отображения убедитесь, что вы задали параметр splitOn, если у вас есть ключи, отличные от Id». Я уже установил splitOn, но он работает только без соединения. Может быть, я делаю что-то неправильно. –

+0

Он работает! Мне пришлось использовать splitOn: «Id, ExtraDataValue, Id». Первый идентификатор для клиента и последний для адреса. Странно, но это сработало. Большое спасибо. Вы хотите изменить свои ответы? Я хотел бы проголосовать за решение. –

+0

@ CassioTavares сделано. – XenoPuTtSs

2

Я просто искал это для себя. Это то, что я придумал, изменил ваш сценарий.

class Customer 
{ 
    public int Id {get;set;} 
    public int Name {get;set;} 
    public ExtraData Extra {get;set;} 
} 

class ExtraData 
{ 
    public int Value {get;set;} 
    public int Date {get;set;} 
} 

using (var conn = DatabaseService.CreateConnection()) 
{ 
    var t = conn.Query<Customer, ExtraData, Customer>(@" 
    select 
     cust_num as Id, 
     cust_name as Name, 
     ex_data1 as Value, 
     ex_date as Date 
    from Customer 
    ", 
    (cust, extra) => 
    { 
     cust.Extra = extra; 
     return cust; 
    }, 
    splitOn: "Value"); 
    return t; 
} 
+0

Я протестировал ваше решение, и оно работает, но в моем случае это не сработало, потому что у меня есть соединение с другой таблицей. Я действительно не знаю, должен ли я отмечать ваш ответ как решение, потому что он не работает во всех случаях. Я понимаю, что это ограничение Dapper и, возможно, у нас нет лучшего решения. Я подожду какое-то время, чтобы узнать, есть ли у нас другая идея. Благодарю. –

+0

Вы можете оставить свой запрос? Я обновил свой ответ, чтобы получить запрос, который присоединяется к таблице «extraData». – XenoPuTtSs

+0

Извините, я не был достаточно ясен. Экстрадаты находятся в одной таблице, как и в первый раз. У меня есть соединение с другой таблицей (Not ExtraData). В моем случае это таблица адресов. Я думаю, вам нужно откат к вашему последнему ответу, потому что это было правильно. –

Смежные вопросы