blackraist
blackraist

Reputation: 183

linq inline string operation

I've a method that returns this exception. LINQ to Entities does not recognize the method 'System.String stringCutter(System.String)' method, and this method cannot be translated into a store expression.

      public List<ProductReqNoDate> GetRequestsQuery()
    {
      var query = (from r in db.talepler
                     select new ProductReqNoDate
                     {
                         talepEdenBirim = r.talepEdenBirim,
                         talepNo = r.talepNo,
                         talepTarihi = r.talepTarihi,
                         urunAdi = stringCutter((from p in db.urunler
                                                 where p.talepNo == r.talepNo
                                                 select p.urunAd).FirstOrDefault()) // <--This
                     }).AsQueryable();
     return query.ToList();
     }
       string stringCutter(string txt)
    {
        return string.IsNullOrEmpty(txt) ? "" : txt.Length <= 30 ? txt : txt.Substring(0, 30) + "...";
    }

when i use this string operations inline, it works. but its too long,

      urunAdi = ((from p in db.urunler where p.talepNo == r.talepNo select p.urunAd).FirstOrDefault()).Length <= 30 ?
                         ((from p in db.urunler where p.talepNo == r.talepNo select p.urunAd).FirstOrDefault()) :
                         ((from p in db.urunler where p.talepNo == r.talepNo select p.urunAd).FirstOrDefault()).Substring(0, 30) + "..."

How can i refer (from p in db.urunler where p.talepNo == r.talepNo select p.urunAd).FirstOrDefault()) as txt maybe; so i can use stringCutter method inline like:

     urunAdi=string.IsNullOrEmpty(txt) ? "" : txt.Length <= 30 ? txt : txt.Substring(0, 30) + "...";

Is there a way of shortening this code. , thanks

Upvotes: 0

Views: 176

Answers (2)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726599

IQueryable<> cannot convert your expression to be used with the back-end store. You need to bring a string into memory first, then you can use IEnumerable<>'s projection method to call your method, like this:

return (from r in db.talepler
    select new // First, use an anonymous type to read the building blocks
    {
        r.talepEdenBirim,
        r.talepNo,
        r.talepTarihi,
        urunAdiStr = (from p in db.urunler
            where p.talepNo == r.talepNo
            select p.urunAd).FirstOrDefault()
    }
).AsQueryable()
.ToList() // Force the data into memory
.Select(anon => new ProductReqNoDate {
    talepEdenBirim = anon.talepEdenBirim,
    talepNo = anon.talepNo,
    talepTarihi = anon.talepTarihi,
    urunAdi = stringCutter(anon.urunAdiStr) // Now stringCutter is available
}).ToList();

Upvotes: 0

Richard
Richard

Reputation: 109015

EF is trying to map the function stringCutter into SQL. Which it can't because it does not know about it. The inline version only uses functions that EF knows to map to SQL expressions/function.

Upvotes: 1

Related Questions