2009-08-21 16 views
6

SQL ile ilgili 2 ilgili Linq var. Modelimin neye benzediğini görmek için lütfen aşağıdaki resme bakın.Kendi kendine başvuru tablosundaki SQL varlıklarına Linq yüklemesi

Soru 1

ben anlamaya çalışıyorum nasıl istekli benim User sınıf/masaya yük User.AddedByUser alanını. Bu alan, User.AddedByUserId alanındaki ilişkiden oluşturulur. Tablo kendi kendini referanslama, veözelliği hevesle yüklemek için Linq SQL almak nasıl anlamaya çalışıyorum, yani User varlık yüklü/getirildiğinde, aynı zamanda User.AddedByUser ve User.ChangedByUser getirmeniz gerekir . Ancak, bu bir özyinelemeli sorun haline gelebilir anlıyoruz ...

Güncelleme 1.1:

var options = new DataLoadOptions(); 
options.LoadWith<User>(u => u.ChangedByUser); 
options.LoadWith<User>(u => u.AddedByUser); 

db = new ModelDataContext(connectionString); 
db.LoadOptions = options; 

Ama bu değil: Ben şöyle DataLoadOptions kullanmayı denedik

nesne grafiği izin verilmez -

System.InvalidOperationException occurred 
    Message="Cycles not allowed in LoadOptions LoadWith type graph." 
    Source="System.Data.Linq" 
    StackTrace: 
     at System.Data.Linq.DataLoadOptions.ValidateTypeGraphAcyclic() 
     at System.Data.Linq.DataLoadOptions.Preload(MemberInfo association) 
     at System.Data.Linq.DataLoadOptions.LoadWith[T](Expression`1 expression) 
     at i3t.KpCosting.Service.Library.Repositories.UserRepository..ctor(String connectionString) in C:\Development\KP Costing\Trunk\Code\i3t.KpCosting.Service.Library\Repositories\UserRepository.cs:line 15 
    InnerException: 

istisna oldukça kendini açıklıyor: iş, ben Hat 2 aşağıdaki istisna almak Döngüsel olmak. Ayrıca, Satır 2'nin bir istisna atmadığını varsayarak, Satır 3'ün yinelenen anahtarlar olduğundan eminim.

Güncelleştirme 1.2:

, takibeden (güncelleştirme 1.1 Yukarıdaki ile paralel olarak kullanılmaz) çalışmaz:

Aşağıdaki, kendini açıklayan durum atar
var query = from u in db.Users 
      select new User() 
      { 
       Id = u.Id, 
       // other fields removed for brevityy 
       AddedByUser = u.AddedByUser, 
       ChangedByUser = u.ChangedByUser, 

      }; 
return query.ToList(); 

:

System.NotSupportedException occurred 
Message="Explicit construction of entity type 'i3t.KpCosting.Shared.Model.User' in query is not allowed." 

Şimdi bunu nasıl çözeceğime dair bir kayıpta GERÇEKTİR. Lütfen yardım et!

benim DB her masada Soru 2

, ve SQL modeline dolayısıyla Linq, ben iki alan, Entity.ChangedByUser ve Entity.AddedByUser (Entity.ChangedByUserId yabancı anahtar/ilişki bağlantılı) (Entity.AddedByUserId yabancı anahtara bağlı olması/ilişki)

Bu alanları benim için yüklemek için Linq'i SQL'e nasıl alabilirim? Sorularıma basit bir katılım mı yapmalıyım yoksa başka bir yol var mı?

Linq to SQL eager loading on self referencing table http://img245.imageshack.us/img245/5631/linqtosql.jpg

cevap

3

Belki bir adım geri atmayı ve ile arasındaki ilişkiyi görmeyi deneyebilirsiniz? Bu bilgiyi kullanıcıya örn. "8 saat önce Iain Galloway tarafından değiştirildi".

Aşağıdaki gibi bir şey olabilir mi? : -

var users = from u in db.Users 
      select new 
      { 
       /* other stuff... */ 
       AddedTimestamp = u.AddedTimestamp, 
       AddedDescription = u.AddedByUser.FullName, 
       ChangedTimestamp = u.ChangedTimestamp, 
       ChangedDescription = u.ChangedByUser.FullName 
      }; 

(imo) netliği için orada anonim bir yazı kullandım. Tercih ederseniz, bu özellikleri Kullanıcı türünüze ekleyebilirsiniz.

İkinci sorunuza gelince, normal LoadWith (x => x.AddedByUser) vb. Çok iyi çalışmalı, ancak açıklama dizgisini doğrudan veritabanında saklamayı tercih etmeme rağmen - bir trade-off var ChangedByUser.FullName değiştiğinde ve ChangedByUser silinirse (örneğin, ON DELETE CASCADE, veya kodunuzdaki boş bir ChangedByUser ile uğraşırsa) karmaşık ve muhtemelen mantıksız bir şeyler yapmak zorundayken, açıklamanız güncellenir.

+0

Evet Bu bilgiyi GUI'mde görüntülemek istiyorum. Bu sorunu anonim tipler kullanmadan çözmeyi umuyordum. Ama sanırım problemi çözmenin tek yoludur. Sorunum, Linq'in SQL'e birçok ilişkiyle başa çıkamamasıyla ilgili mı? –

+0

Na, User sınıfına User.AddedDescription ve User.ChangedDescription alanları ekleyebilir ve sonra bir anon türünü kullanmak zorunda kalmazsınız. Gerçekten çok fazla ilişki ile ilgisi yoktur (örneğinizdeki her ilişki 1: 1'dir). SQL'inizi doğrudan yazıyorsanız, AddedByUser öğesinin tüm özelliklerini (onun AddedByUser'i de dahil olmak üzere) almak istemezsiniz. Muhtemelen ismini ve/veya senin bakış açınız için gereken her türlü bilgiyi almalısın. Imo daha genel bir O/RM problemidir. L2E veya Hazırda Bekletme ile aynı sorunu yaşayacağınızı düşünüyorum. –

0

emin değil Sql Linq ile bu soruna bir çözüm yoktur. Sql Server 2005 kullanıyorsanız, istediğiniz sonucu almak ve sonra DataContext.ExecuteQuery kullanarak yürütmek için ortak tablo ifadeleri kullanan bir (Yinelemeli gibi) Stored Procecdure tanımlayabilirsiniz.

4

Any type of cycles just aren't allowed. LoadWith<T> veya AssociateWith<T>, bağlamdaki her türe uygulandığından, sonsuz bir döngüyü engellemek için hiçbir iç yol yoktur. Daha doğru bir şekilde, SQL Server'ın CONNECT BY ve CTEs olmadığı için SQL'in nasıl oluşturulacağı ile ilgili karışıklık, Linq'in sağlanan çerçeve ile otomatik olarak ne üretebildiğini geçmiş.

Kullanabileceğiniz en iyi seçenek, 1 düzeyi birleştirmeyi, her ikisi için de çocuk masasına ve anonim bir türe dönüştürmek için el ile yapmaktır. Üzgünüz, temiz/kolay bir çözüm değil, ama Linq ile şu ana kadar mevcut olan gerçekten.

İlgili konular