iT邦幫忙

1

Lambda是否可以內嵌函數取值呢?

請教各位大大,如題Lambada是否可以內嵌函數取值呢?
程式碼(全)

List<MemberToConferenceTrackViewModel> result = db.MemberToConferences.Where(mc => mc.MemberId == MemberId && mc.Role == Role).
    Join(db.Conferences.Where(c => c.Enabled == true),
    m => m.ConferenceId,
    c => c.ConferenceId,
    (m, c) => new { m, c })
    .Join(db.EditTrackAssignments.Where(eta => eta.DirectorId == MemberId),
    m => m.m.MemberId,
    e => e.DirectorId,
    (m, e) => new
    {
        e.TrackId,
        m.m.ConferenceId,
        m.m.MemberId,
        m.c.ConferenceTitle
    }).Join(db.ConferenceTracks, x => x.TrackId, ct => ct.TrackId,
    (x, ct) => new
    {
        x.ConferenceId,
        x.ConferenceTitle,
        x.MemberId,
        ct.TrackId,
        ct.TrackTitle
    }).Join(db.Members, x => x.MemberId, m => m.MemberId,
    (x, m) => new MemberToConferenceTrackViewModel
    {
        ConferenceId = x.ConferenceId,
        ConferenceTitle = x.ConferenceTitle,
        MemberId = x.MemberId,
        MemberName = m.Name,
        TrackId = x.TrackId,
        TrackTitle = x.TrackTitle,
        PaperNum = GetStatusPaperNumbers(x.ConferenceId, 5)
    })
    .ToList();

取值時其中一個變數想要透過另外函數統計取值,但報錯!

LINQ to Entities 無法辨識方法 'Int32 GetStatusPaperNumbers(Int32, Int32)' 方法,而且這個方法無法轉譯成存放區運算式。

取值程式碼如下

PaperNum = GetStatusPaperNumbers(x.ConferenceId, 5)

目前知道的方法是可以ToList()輸出後再重新用ForEach跑廻圈帶函數取值?
請問是否有其它更好的方法可以替代解決呢?

fillano iT邦超人 1 級 ‧ 2019-12-17 17:18:04 檢舉
沒有,Linq for Entities最後會轉成sql來執行,你必須給他他轉得了的東西。
sion iT邦新手 4 級 ‧ 2019-12-17 17:33:40 檢舉
可以看看這方法
https://dotblogs.com.tw/terrychuang/archive/2011/07/25/32090.aspx

1 個回答

0
舜~
iT邦好手 1 級 ‧ 2019-12-18 08:11:12

只有資料來源不是資料庫的才可以用內嵌函數

因為資料來源是資料庫的最後都會轉成sql,大多內建函數與您自訂的函數都無法轉成sql

想到幾個折衷的解決方法

  1. 把資料庫資料先抓出來放在記憶體中(不能延遲執行),這樣就能擺脫Linq-to-sql / Linq-to-Entities / Linq-to-DataSets 就有機會可以用您的函數
    不過這樣就無法利用資料庫的索引,且要小心您的記憶體會被這些未處理/處理到一半的資料占滿

  2. 先在外面取得您函數的結果(也許是陣列,也許是值),這樣您的Lambada就用不到該函數了

  3. 將您的方法用Lambada/Linq表達重寫,或是放到資料庫的預存程序/方法中(參考sion大給的連結)

我要發表回答

立即登入回答