2011-11-26 10 views
5

LINQ için oldukça yeni ve başımdaki bazı tutarsızlıklar davranışta bulunamıyor. Bilgili herhangi bir girdi çok takdir edilecektir. SO ve benzeri yerlerde benzer sorunlar görüyorum ama yardım etmiyorlar.LINQ - 'Önceden kullanılan ve kanıtlanmış sorgu koşuluyla ifade ifadesi tercüme edilemedi'

Çok basit bir kurulumum var - bir şirket masası ve bir adres tablosu. Her şirket 0 veya daha fazla adrese sahip olabilir ve> 0 olanı ana adres olarak belirtilmelidir. Ben bir dış birleştirme kullanarak ve buna göre seçim deyimini değiştirerek, 0 adresleri var durumları ele almaya çalışıyorum.

Lütfen şu anda çıktıyı doğrudan bir GridView'e bağladığımı unutmayın, bu nedenle tüm işlemleri sorguda tutmak istiyorum.

aşağıdaki eser

IQueryable query = 
    from comp in context.Companies 
    join addr in context.Addresses on comp.CompanyID equals addr.CompanyID into outer // outer join companies to addresses table to include companies with no address 
    from addr in outer.DefaultIfEmpty() 
    where (addr.IsMain == null ? true : addr.IsMain) == true // if a company has no address ensure it is not ruled out by the IsMain condition - default to true if null 
    select new { 
     comp.CompanyID, 
     comp.Name, 
     AddressID = (addr.AddressID == null ? -1 : addr.AddressID), // use -1 to represent a company that has no addresses 
     MainAddress = String.Format("{0}, {1}, {2} {3} ({4})", addr.Address1, addr.City, addr.Region, addr.PostalCode, addr.Country) 
    }; 

YAPAR ama bu ", ,()"

yüzden

MainAddress = (addr.AddressID == null ? "" : String.Format("{0}, {1}, {2} {3} ({4})", addr.Address1, addr.City, addr.Region, addr.PostalCode, addr.Country)) 

olmak MainAddress alanını güncellenerek olarak GridView boş adresini görüntüler şimdi Could not translate expression hatası alıyorum ve bir grup otomatik olarak oluşturulmuş kodu r benim için çok az anlamına geliyor.

MainAddress'e eklediğim koşul, AddressID'deki çalışma koşulundan farklı değil, bu yüzden burada neler olduğunu kimse anlatabilir mi?

Herhangi bir yardım büyük beğeni topladı.

+2

soruya "spewey otomatik olarak oluşturulan kod" eklemek istediğiniz olabilir. – Bert

cevap

6

Aldığınız hata, LinqToSql'in null denetiminizi ve sonra string.Format ifadesini SQL'e çeviremeyeceğini bildirmektir. Eğer işlemek için bir CASE-WHEN kullandığını görebilirsiniz, sizin AddressID alanı için

SELECT [t0].[CompanyID], [t0].[Name], 
    (CASE 
     WHEN [t1].[AddressID] IS NULL THEN @p0 
     ELSE [t1].[AddressID] 
    END) AS [AddressID], 
    [t1].[Address1] AS [value], 
    [t1].[City] AS [value2], 
    [t1].[Region] AS [value3], 
    [t1].[PostalCode] AS [value4], 
    [t1].[Country] AS [value5] 
FROM [Company] AS [t0] 
LEFT OUTER JOIN [Address] AS [t1] ON [t0].[CompanyID] = [t1].[CompanyID] 
WHERE ([t1].[IsMain] IS NULL) OR ([t1].[IsMain] = 1) 

: Eğer SQL ilk sorgu (LINQPad veya SQL Profiler kullanarak) oluşturuyor bakarsak, gibi bir şey göreceksiniz AddressID durumunun boş olduğu durum. MainAddress için bir CASE-WHEN eklediğinizde, bu alan için aynı şeyi yapmaya çalışıyor, ancak ELSE yan tümcesi için kullanabileceğiniz bir SQL eşdeğeri, bu yüzden bu kadar patlar.

Bu soruna geçici bir çözüm, dizeyi biçimlendirmek için bir yöntem kullanmaktır. Özel bir yöntemi çağırarak, LinqToSql, string.Format'u SQL'e çevirmeyi denemez ve bunun yerine Address nesnesini doldurmak için gerekli tüm alanları döndürür. Yöntem daha sonra biçimlendirmeye dikkat edebilir. Örneğin

:

LINQ:

.... 
select new { 
    comp.CompanyID, 
    comp.Name, 
    AddressID = (addr.AddressID == null ? -1 : addr.AddressID), 
    MainAddress = FormatAddress(addr) 
}; 

Yöntem:

private static string FormatAddress(Address addr) 
{ 
    return (addr == null ? "" : 
      string.Format("{0}, {1}, {2} {3} ({4})", 
         addr.Address1, addr.City, 
         addr.Region, addr.PostalCode, addr.Country)); 
} 
+0

Harika yardım ve açıklama için teşekkürler. LINQ'in hangi bölümlerini denemeye ve veritabanına geçeceğinin farkında değildim. Ben her zaman bu çılgın şeyler hakkında daha fazla şey öğreniyorum ... – tomfumb

+0

Serin, memnun olabilirdim. – rsbarro