2012-01-28 24 views
5

Cevabın kesin olduğunu biliyorum. Son bir deneme girişimi olarak bu soruyu sormam gerektiğini düşündüm. Ben öncelikle aşağıdaki ifadeyi (ben sadece bu yüzden yanlış olabilir yazdım) oluşturur zamanki modaBir IQueryable ifadesini manuel olarak değiştirmek mümkün mü?

_context.Set<Foo>().Where(f => f.Bar == 999); 

bir tablo sorgulamak için EF kodunu kullanıyorum

.

{SELECT 
[Extent1].[Test] AS [Test], 
[Extent1].[Test2] AS [Test2], 
FROM [dbo].[Foo] AS [Extent1] 
WHERE 19 = [Extent1].[Bar]} 

Şimdi, elle Foo10, diyelim ki, tablo adını değiştirmek için bu sorguyu değiştirmek mümkün mü? (Muhtemelen değil)

Bunu yapan kişi, önce koddaki tablo adını "geç" olarak değiştirebileceğim bir yol biliyor mu?

Muhtemelen "Neden kirli kesmek?" Diye merak ediyorsun. Her zamanki gibi, bu, bazı tasarım sorunları olan ve değiştirilemeyen bir veritabanıyla eski bir sorundur.

Şimdiden teşekkürler.

Ps. Database.SqlQuery'u kullanabileceğimin farkındayım ama yapmamayı tercih ederim.

+0

Neden modelinizde Foo10' tablonuz yok? – BrokenGlass

+0

Teknik olarak aynı model birden fazla tabloya yayılıyor. Verilerinizin bulunduğu tablo, –

+0

(mjmcloug) parametresine bağlı olarak değişir, nasıl bağlıdır? – Krizz

cevap

0

Bu, öneride bulunacağım bir şey değil, ancak ToString() yöntemine bir SQL değişkenini bir değişkene koymak için sorgulama yapabilirsiniz. Sonra SQL bu SQL yürütmek?

Koklamak ve hacky ama mümkün mü?

+0

Bildiğim kadarıyla, yalnızca Entity Framework'ü kullanmaktan vazgeçmek istemeniz halinde mümkündür, bu da SQL'i yine de elle yazmanız anlamına gelir. – Bevan

+0

Bunu yapmayı düşündüm. Bu verinin sadece okunabilmesi muhtemeldir, bu yüzden uygun olabilir. Bunun biraz tehlikeli olduğunu düşünün: D –

+0

@Bevan, toplam atığı değil. Her zamanki deyim için –

1

Makul sayıda tabloya sahip olduğunuzu varsayarak, bunların hepsini modele ekleyebilir ve tüm sınıfların uygulayacağı ortak bir arabirim oluşturabilir ve ardından yeterli modeli seçebilir ve sorgulama için Dynamic Linq'u kullanabilirim. Umarım bu işe emin değilim

, bunu kontrol etmedim ve "EF kod ilk" ile çalıştı değil, ama bu denemek istiyorum şeydir:

en tablonuzu (ler) diyelim FooBar, Pub, X alanları ve X alanlarının ilgili tabloya bağlı olmasını sağlayın mı?

interface IFoo 
{ 
    int Bar { get; set; } 
    string Pub { get; set; } 
    int X { get; set; } 
} 

Daha sonra her tablo analizinde devam sınıfını sahip olacaktır::

Sonra ben arayüzünü tanımlarsınız

[Table("Foo1")] 
class Foo1 : IFoo 
{ 
    public int Bar { get; set; } 
    public string Pub { get; set; } 
    public int X { get; set; } 
} 

[Table("Foo2")] 
class Foo2 : IFoo 
{ 
    public int Bar { get; set; } 
    public string Pub { get; set; } 
    public int X { get; set; } 
} 

Sonra aşağıdaki gibi onları filtre olabilir:

IQueryable GetAdequateFoo(int X) 
{ 
    switch (X) // you could use reflection here to dynamically call the given Set<Foo#>() 
    { 
     case 1: 
     return _context.Set<Foo1>(); 
     case 2: 
     return _context.Set<Foo2>(); 
     default: 
     return null; 
    } 
} 

IFoo GetFooByBarAndX(int bar, int X) 
{ 
    IQueryable context = GetAdequateFoo(X); 
    return context.Where("it.Bar == @0", bar).Cast<IFoo>(); 
} 

Sadece test edilmemiş bir öneri ve kafasından yazılıyor, lütfen yanlıs olmadığım takdirde yanlış oy vermeyin ve herhangi bir potense dikkat edin tial problemler.

+0

Ha, bu cevabı oylamayacağım, aslında EF'ye bir fabrika yöntemi uygulamak için oldukça akıllıca bir fikir. Bir düşüncem de olacak, aynı zamanda sınıfları da haritalandırdığımdan, bunu kurmak için çok fazla ders var. Zekice bir fikir olsa! –

2

Modelinizde neden TPT devralmayı kullanmıyorsunuz?

Krizz'in yanıtına benzer, ancak dinamik LINQ kullanmaktan kaçınıyorsunuz.Belirli bir parametre foo1 1 görünüm bir değeri varsa foo2 ve böylece Yani

üzerindeki 2 göz, bunu eğer

:

Yorumunuzu kullanma

:
var query = ctx 
    .Foos 
    .OfMyType(value) 
    .Where(f => f.Bar == 999) // f.Bar is on the base/abstract entity. 
    .ToList(); 

OfMyTypeIQueryable<T> ilgili özel bir uzantı yöntemidir

public static IQueryable<T> OfMyType<T>(this IQueryable<T> source, string value) 
{ 
    switch (value) 
    { 
     case "1": 
     return source.OfType<Foo1>(); 
     case "2": 
     return source.OfType<Foo2>(); 
     // etc, etc 
    } 
} 

Özelliklerin çoğu (tümü olmasa da), soyut "Foo" varlık üzerinde olacak ve her birinin kendi destek masasına sahip olan her bir tablo için türetilmiş varlıklar oluşturursunuz.

Bu şekilde, "tüketen" kod (örneğin, sorguları yapanlar), farklı tablolar/Foo'ların umrunda değil, sadece "sihirli değeri" depoya (umarız sizin kullandığınız şekilde) geçirirler. İstediğiniz tabloya sessizce geçebilirsiniz.

Bu işe yarar mı?

+0

Yine bu iyi görünüyor. Onu bir ver ve sana geri dönmeliyim. Ama yine de tek meselem, kaçınmaya çalıştığım bir sürü ders üretmek anlamına geliyor. Mirasını sevmek zorundasın! –

+1

+1 Hangi çerçeve önerilerini kullanarak yaklaşımımı kolaylaştırmak güzel. – Krizz

İlgili konular