Arkaplan
I veya belirli bir tarihten önce oluşturulan kayıtları aşağı sonuçları filtreleyen bir .Include inşa etmek gerekiyor. Orijinal LINQ deyimindeki nesnelerin türlerini bilmeyeceğim ve onları bulmaya çalışacağım (bir sürü halka aracılığıyla, ama bu işe yarıyor). Orijinal linq yazarken yani bir geliştirici bu ilişkileri yazın vermez (dinamik Dahil, Build ile nerede Filtre
A -> Ac
/\
Bc <- B \
/ \
Cc <- C D -> Dc
Nesneler Ac
, Bc
, Cc
ve Dc
tüm dinamik olarak bulunurlar:
böyle nesnelerin bir grafik var Beyan). Bunlar daha sonra bir IQueryable ifadesine eklenmeli ve değerleri yalnızca belirli bir DateTime'a döndürmelidir.
Kod So Far
Bir lambda oluşturur ve tarihleri karşılaştıran bir işlevi oluşturmak çalıştı. Şimdiye kadar, eğer orijinal sorgu A.Include(x => x.B).Include(x => x.B.Select(y => y.C)
ise, "A.B.Bc"
dizesini oluşturabilirim, böylece A, B ve Bc türlerini ve bunların ilişkilerini biliyorum.
private static IQueryable<T> FilterChangeTrackerToDate<T>(this IQueryable<T> query, string includeString, DateTime targetDateTime)
{
var param = Expression.Parameter(typeof(T), "x");
var prop = Expression.Property(param, includeString + ".CreatedUtc");
var dateConst = Expression.Constant(targetDateTime);
var compare = Expression.LessThanOrEqual(prop, dateConst);
var lambda = Expression.Lambda<Func<T, bool>>(compare, param);
return query.Where(lambda);
}
konu "A.B.Bc.CreatedUtc"
tarih özelliği yüklemek için doğru yol değildir, çünkü yukarıdaki kod çöküyor olmasıdır - Ben .Select
ifadeleri ile bu hareket etmesi gerekli. Her iki amacıyla
Sorun
yük kayıtları ve onları, ben dinamik olarak (minnetle, miras dayalı statiktir) Ben gereken değerleri çekme yönündeki bir .Select
inşa etmek gerekfiltre ve bu değerleri anonim bir türe yerleştirin, daha sonra bir .Where()
ile filtrelenebilir. Bunların hepsinin asgari jenerikle yapılması gerekiyor, çünkü derleme zamanı türlerini doğrulamamak için kullanmam gerekiyor ve ben de bunları işe almak için yansımayı kötüye kullanmak zorundayım.
Esasen, ben bu oluşturmanız gerekir:
.Select(x => new
{
Bc = x.B.Select(z => z.Bc.Select(y => y.CreatedUtc).Where(q => q > DateTime.UtcNow)),
A= x
})
dinamik, yuvalama herhangi bir düzeyi için, dize "A.B.Bc" seçeneğini kullanarak. sadece üst düzey değerlerini seçer ve görünmüyor dinamik bir seçin oluşturma hakkında LINQ To Entities Include + Where Method
Bu mesaj görüşmelerini ama: Ben EF filtrelemek nasıl gördüğünü burasıdır
Kaynaklar
yöntemini içerir How to create LINQ Expression Tree to select an anonymous type
Dinamik Linq System.Linq kullanma
: gibi benim problem için gerekli parçaların kalanını inşa edebilirsiniz.Dinamik kütüphane, ben Bc kapalı CreatedUtc
değerini erişmeye çalıştık:
includeString = "B.Bc"
query = (IQueryable<T>) query.Select(includeString + ".CreatedUtc");
ama bu bana ait bir istisna verir:
Exception thrown: 'System.Linq.Dynamic.ParseException' in System.Linq.Dynamic.dll
Additional information: No property or field 'Bc' exists in type 'List`1'
, bu hatayı alıyorum: 'Ek bilgi: Hiçbir tesisin veya alanın 'Bc' türü var 'List'1''. İç içe geçmiş grafikleri doğru şekilde incelemek gibi görünmüyor mu? – Max
Kodunuzun daha fazlasını burada gösterebiliyor musunuz? –
Ana sayfamı güncelledim. – Max