SORU
16 HAZİRAN 2011, PERŞEMBE


Multi-Okuma nesne hiyerarşi oluşturmak için

documented posts/users example ama onun biraz farklı gibi geliyor gibi görünüyor, çünkü bir süre için bu ile oynamak oldum ve benim için işe yaramıyor.

Aşağıdaki basit kurulum (bir kişi için birden fazla telefon numaraları var) varsayarsak:

public class Contact
{
    public int ContactID { get; set; }
    public string ContactName { get; set; }
    public IEnumerable<Phone> Phones { get; set; }
}

public class Phone
{
    public int PhoneId { get; set; }
    public int ContactID { get; set; } // foreign key
    public string Number { get; set; }
    public string Type { get; set; }
    public bool IsActive { get; set; }
}

Birden fazla Telefon nesneler ile Temas döndüren bir şey ile bitirmek isterim. Eğer 2 rehber, 2 telefonları her biri olsaydı, benim SQL 4 toplam satır ile bir sonucu olarak bu birleşim bir dizi döndürür. O zaman çok Şık iki telefon her ile 2 kişi nesneleri pop olur.

Burada saklı yordam SQL:

SELECT *
FROM Contacts
    LEFT OUTER JOIN Phones ON Phones.ReferenceId=Contacts.ReferenceId
WHERE clientid=1

Bunu denedim, ama 4 Dizilerini TAMAM, ama umduğum şey... sadece ben hala yeniden normale sonucu var demek değil) ile sona erdi:

var x = cn.Query<Contact, Phone, Tuple<Contact, Phone>>("sproc_Contacts_SelectByClient",
                              (co, ph) => Tuple.Create(co, ph), 
                                          splitOn: "PhoneId", param: p, 
                                          commandType: CommandType.StoredProcedure);

ve başka bir yöntem çalıştığımda (aşağıda), "türü 'System.object atama Yapılamıyor bir istisna olsun'Türü 'System.Int32 Koleksiyonları.Jenerik.Ienumerable`1[Telefon]'."

var x = cn.Query<Contact, IEnumerable<Phone>, Contact>("sproc_Contacts_SelectByClient",
                               (co, ph) => { co.Phones = ph; return co; }, 
                                             splitOn: "PhoneId", param: p,
                                             commandType: CommandType.StoredProcedure);

Sadece yanlış bir şey mi yapıyorum? Mesaj gibi/örnek sahibi oluyor, üst alt yerine alt üst edeceğim.

Şimdiden teşekkürler

CEVAP
17 HAZİRAN 2011, Cuma


- Yanlış bir şey yapmıyorsun, sadece API tasarlanmıştır yolu bu değildir. Query API tümher zamanveritabanı satır başına bir nesne döndürür.

Yani, bu çok ^ üzerinde çalışıyor . bir ya da daha az bir ^ yön . çok-çok göster.

2 sorunları var:

  1. Biz sizin Sorgu ile çalışan bir dahili eşleyici tanıtmak, "" yinelenen veri. atılması bekleniyor oluruz (Rehber*. senin sorguda yinelenen)

  2. Biz bir ^ ile çalışmak için tasarım . birçok çift, kimlik göster çeşit ihtiyacımız olacak. Karmaşıklık ekler.


Al örneğin bu sorgu hangisi verimli olursa senin sadece çekme sınırlı sayıda kayıtları, eğer zorlarsan bu bir milyon şeyler yanıltıcıdır, çünkü ihtiyacınız akışı ve can not load her şeyi içine bellek:

var sql = "set nocount on
DECLARE @t TABLE(ContactID int,  ContactName nvarchar(100))
INSERT @t
SELECT *
FROM Contacts
WHERE clientid=1
set nocount off 
SELECT * FROM @t 
SELECT * FROM Phone where ContactId in (select t.ContactId from @t t)"

Ne yapabileceğini yeniden eşleştirme için izin GridReader uzatmak

var mapped = cnn.QueryMultiple(sql)
   .Map<Contact,Phone, int>
    (
       contact => contact.ContactID, 
       phone => phone.ContactID,
       (contact, phones) => { contact.Phones = phones };  
    );

Size GridReader genişletmek ve bir eşleyici ile varsayarsak:

public static IEnumerable<TFirst> Map<TFirst, TSecond, TKey>
    (
    this GridReader reader,
    Func<TFirst, TKey> firstKey, 
    Func<TSecond, TKey> secondKey, 
    Action<TFirst, IEnumerable<TSecond>> addChildren
    )
{
    var first = reader.Read<TFirst>().ToList();
    var childMap = reader
        .Read<TSecond>()
        .GroupBy(s => secondKey(s))
        .ToDictionary(g => g.Key, g => g.AsEnumerable());

    foreach (var item in first)
    {
        IEnumerable<TSecond> children;
        if(childMap.TryGetValue(firstKey(item), out children))
        {
            addChildren(item,children);
        }
    }

    return first;
}

Bu olduğu için biraz zor ve karmaşık uyarılar ile. Temel olarak, bu da dahil olmak üzere doğru eğilerek değilim.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Incredible Tutorials

    Incredible T

    27 EKİM 2006
  • KoreanFrogMania님의 채널

    KoreanFrogMa

    18 Aralık 2011
  • KRQE

    KRQE

    6 AĞUSTOS 2007