olan bir sarmalayıcı nesnesi oluştururken Include
sorgumda gezinme özelliğini ekliyorum, böylece daha sonra yüklenmeyecek. Ancak, Select
projeksiyon ile anonim bir sarmalayıcı nesne oluşturduğumda işe yaramıyor.EF: "İçine Ekle" gezinme özelliği, "Seçim" projeksiyonu
Basitleştirilmiş örneği göstereyim. varlık:
public class UserEntity {
public string Name {get;set;}
public virtual ICollection<UserEntity> Friends { get; set; }
}
sorgu: Ben oluşturulan SQL ayrıca bkz
var entry = _dbCtx
.Users
.Include(x => x.Friends)
// Select here is simplified, but it shows the wrapping
.Select(user => new {
User = user
})
.First();
// Here we have additional lazy loaded DB call
var friends = entry.User.Friends.Select(x => x.Name).ToList();
Ve bu navigasyon özelliği dahil değildir:
SELECT
[Limit1].[Name] AS [Name],
FROM (SELECT TOP (1)
[Extent1].[Name] AS [Name]
FROM [dbo].[Users] AS [Extent1]
) AS [Limit1]
mümkün mü Include
'a göre navigasyon özelliği Friends
Bu durumda, User
, tembel yükleme olmadan veri alacak?
var entry = _dbCtx
.Users
.Select(user => new {
User = user
})
.Include(x => x.User.Friends)
.First();
Ama bir özel durum alma:
Ben bu işe de bekliyordumInvalidOperationException: Sorgunun sonuç tipi bir EntityType ne de bir varlık unsuru türüyle bir CollectionType ne olduğunu . İçerme yolu, yalnızca bu sonuç türlerinden birine sahip bir sorgu için belirtilebilir.
Orada geldi bazı geçici çözümler vardır, ancak bunlar her nasılsa zor şunlardır:
Select
bizim anonim nesneye ekleme özelliğini ekleyin:var entry = _dbCtx .Users .Select(user => new { User = user, UsersFriends = user.Friends }) .First(); // manually copy the navigation property entry.User.Friends = user.UsersFriends; // Now we don't have any addition queries var friends = entry.User.Friends.Select(x => x.Name).ToList();
Harita ayrıca Kullanıcı DB düzeyinde anonim nesne ve C#
UserEntity
özelliklerini eşlemek.var entry = _dbCtx .Users .Select(user => new { User = new { Name = user.Name, Friends = user.Friends } }) .Take(1) // Fetch the DB .ToList() .Select(x => new { User = new UserEntity { Name = x.Name, Friends = x.Friends } }) .First(); // Now we don't have any addition queries var friends = entry.User.Friends.Select(x => x.Name).ToList();
Yani şimdi, Friends
için LEFT OUTER JOIN
yoktur, ancak her iki geçici çözümler oldukça iyi değildir:
1) Ek özellikler ve bir kopyası temiz bir yol değildir.
2) UserEntity ürünümün başka özellikleri var. Ayrıca, her yeni mülk eklediğimizde, buradaki seçicileri de değiştirmeliyiz.
İlk örnekten de dahil olmak üzere gezinme özelliğini elde etmenin bir yolu var mı?
Okuduğunuz için teşekkür ederim ve umarım birinin bunun için bir ipucu vardır.
DÜZENLEME:
Ben gerçek kullanım senaryosunu göstermek için varlık ve sorguyu uzatacaktır.
Varlık
public class UserEntity {
public string Name {get;set;}
public int Score {get;set;}
public virtual ICollection<UserEntity> Friends { get; set; }
}
Sorgu _why_ olarak
var entry = _dbCtx
.Users
.Include(x => x.Friends)
.Select(user => new {
User = user,
Position = _dbCtx.Users.Count(y => y.Score > user.Score)
})
.First();
biz (sorgusunun ardından) 'C#' tarafında bir sarıcı nesne oluşturmak Olarak örnek çalışacak, değil sql' 'ile: Eğer EF sorgusunun dışında nesne (ler) kapsüllü ne. Ama buna db düzeyinde ihtiyacım vardı. Nedeni: "Seç" ile ek alt sorgu gerçekleştiriyorum. İlginç bir şey, benim ilk geçici çözümümüzü görmemize rağmen, 'user.Friends' sorgusunda kullanıyoruz, ancak materyalizasyondan sonra Mülkiyet'i tekrar objeye kopyalamamız gerekiyor, aksi takdirde yine de tembel bir yükleme olacaktı. – tenbits
Neden db sorgusunda anonim bir türe yansıtmanız gerekiyor? Anladığım kadarıyla aynı sonucu elde edersin. Yoksa, SQL'e yansıtmak istediğiniz _additional_ yöntemlerini ('Where',' OrderBy', vb.) Mi yansıtıyorsunuz? –
Gönderi düzenlemelerime bakın, bir kullanıcı için alt sorgu yapıyorum ve her kullanıcı üzerinde yinelediği için DB'de yapılmalıdır. Performans nedeniyle, bunu C# ile yapamıyorum. – tenbits