簡體   English   中英

如何將此Lambda表達式轉換為linq

[英]How to convert this lambda expression to linq

我看不到復雜的lambda表達式,只有超級基本的lambda表達式,我知道我才剛剛開始學習lambda。

正如我上面的標題一樣,如何將此Lambda轉換為linq?

var train = db.Certificates
            .Join(db.TrainingSchedules, a => a.CertificateId, b => b.CertificateId, (a, b) => new { a, b })
            .Where(x => x.a.Year.Value.Year == year && x.a.TrainingTypeId.Value == trainingTypeId && x.a.IsApproved.Value && x.b.EndDate >= DateTime.Now)
            .Select(z => z.a).Distinct().Where(q => !db.Registrations.Where(s => s.EmployeeId == empId).Select(t => t.Certificate).Any(u => u.CertificateId == q.CertificateId));

有人可以向我解釋為什么它具有不同的變量嗎? x , q , z , b

正如我上面的標題一樣,如何將此Lambda轉換為linq?

你們每個人都在Linq工作過,以了解它的外觀嗎?

如果上面指定的代碼不是Linq ,那么什么是LinqLambdafluentLinq表示的組成部分,因為大多數API都需要Func delegate ,因此Lambda便是其中的Func delegate

現在關於x , q , z , b ,它們代表什么?

Linq API不過是IEnumerable<T>擴展方法,例如List<T>Dictionary<TK,TV> ,無論我們編寫syntax these variables represent, each and every element in the collection, which is processed as part of logic provided by thefluent' or the Sql syntax these variables represent, each and every element in the collection, which is processed as part of logic provided by the Func Delegate syntax these variables represent, each and every element in the collection, which is processed as part of logic provided by the , you can certainly use and should use more credible variable to represent the exact thing, similar to other parts of code where int x,float y,DateTime z`是一種不好的編碼方式

關於以上發布的聲明,請考慮以下更改:

  • a,b重命名為cert,ts ,分別引用CertificateTraining Schedule
  • 與其生成匿名類型new { a, b } ,而不是像CerificateTrainingSchedule這樣創建一個class ,該類分別具有CertificateTraining Schedule類的所有元素,隨着前進,它會更容易工作。
  • x重命名為cts ,以表示組合的CerificateTrainingSchedule
  • 如果它易於閱讀,則在多個鏈中將Where子句分開,例如:

     .Where(cts => cts.a.Year.Value.Year == year) .Where(cts => cts.a.TrainingTypeId.Value == trainingTypeId) .Where(cts => cts.a.IsApproved.Value) .Where(cts => cts.b.EndDate >= DateTime.Now) 
  • 同樣,可以修改其他變量的名稱以表示真實的類及其對象,而不是隨機的a,b,c,d 還可以將調用鏈接起來以清楚地了解邏輯

編輯-//修改的Linq查詢

//加入/合並的證書和培訓計划版本,根據需要添加更多字段,當前字段分別基於對Certificate&TrainingSchedule類中的字段/屬性的某些假設

public class CertificateTrainingSchedule
{
   public int Year {get; set;} // Certificate Class Property
   public int TrainingTypeId {get; set;} // Certificate Class Property
   public bool IsApproved {get; set;} // Certificate Class Property
   public DateTime EndDate {get; set;} // TrainingSchedule Class Property
}

var train = db.Certificates
            .Join(db.TrainingSchedules, cert => cert.CertificateId, ts => ts.CertificateId, (cert, ts) => new CertificateTrainingSchedule{ Year = cert.Year, TrainingTypeId = cert.TrainingTypeId, IsApproved = cert.IsApproved,EndDate = ts.EndDate})
            .Where(cts => cts.Year == year)
            .Where(cts => cts.TrainingTypeId == trainingTypeId)
            .Where(cts => cts.IsApproved)
            .Where(cts => cts.EndDate >= DateTime.Now)
            .Select(cts => new {cts.Year,cts.TrainingTypeId,cts.IsApproved})
            .Distinct() // Allowing anonymous type to avoid IEqualityComparer<Certificate>
            .Where(certMain => !db.Registrations.Where(s => s.EmployeeId == empId)
                                                .Select(cert => new Certificate{Year = cert.Year,TrainingTypeId = cert.TrainingTypeId,IsApproved = cert.IsApproved})
                                                .Any(cert => cert.CertificateId == certMain.CertificateId))

我假設通過您的問題,您的意思是您想要一個等效於顯式調用LINQ方法的查詢表達式。 沒有良好的最小,完整和可驗證的代碼示例 ,就不可能確定確切的示例是什么。 但是,以下是我相信您正在尋找的東西:

var train =
    from q in
         (from x in
              (from a in db.Certificates
               join b in db.TrainingSchedules on a.CertificateId equals b.CertificateId
               select new { a, b })
          where x.a.Year.Value.Year == year && x.a.TrainingTypeId == trainingTypeId &&
                x.a.IsApproved.Value && x.b.EndDate >= DateTime.Now
          select x.a).Distinct()
     where !(from s in db.Registrations where s.EmployeeId == empId select s.Certificate)
       .Any(u => u.CertificateId == q.CertificateId)
     select q;

請注意,並非所有的LINQ方法都具有等效的C#查詢表達式語言。 特別是, Distinct()Any()沒有等效項,因此它們仍被明確地寫出。

有人可以向我解釋為什么它具有不同的變量嗎? 像x,q,z,b一樣?

每個lambda表達式的輸入都在=>的左側,而結果表達式在右側。 您要引用的變量是輸入。 這些在編寫lambda表達式時通常使用單個字母編寫,因為lambda表達式非常短,因此無需較長的變量名即可清楚理解。 因此,獨立的lambda表達式甚至可以使用相同的變量名。

請注意,在查詢表達式語法中,並非所有變量都“成功”。 特別是,我們丟失了zt因為這些變量是多余的。

在這么長時間的表達式中,可能會發現較長的變量名很有用。 但這是一個權衡。 查詢表達語言旨在提供一種表示數據源查詢的緊湊方式。 較長的變量名可能會使得更難理解查詢本身,即使它可能使更容易理解表達式的各個部分的意圖也是如此。 這很大程度上取決於個人喜好。

我看不到復雜的lambda表達式,只有超級基本的lambda表達式,我知道我才剛剛開始學習lambda。

嘗試閱讀以下內容:

var train = db.Certificates
    .Where(c => c.Year.Value.Year == year && 
                c.TrainingTypeId.Value == trainingTypeId &&
                c.IsApproved.Value &&
                c.TrainingSchedules.Any(ts => ts.EndDate >= DateTime.Now) &&
                !c.Registrations.Any(r => r.EmployeeId == empId));

如果可以,那么就很好。

請注意,這並非示例查詢的確切翻譯,但在功能上等效(應產生相同的結果)。 示例查詢是寫得不好的查詢的一個很好的例子-變量命名,不必要的乘法Join ,這需要一個Distinct運算符(而GroupJoin將執行相同的操作而不需要Distinct ),兩個相似的詳細條件的不一致處理( Join for TrainingSchedulesAnyRegistrations ), Registrations部分的標准過於復雜等。

不久,請勿編寫此類查詢。 集中查詢的期望結果,並使用最合乎邏輯的結構來表達它。 具有導航屬性時,請避免手動聯接。 如果您沒有導航屬性,則將它們添加到模型中-這是一項簡單的一次性操作,在編寫查詢時會很有幫助。 例如,在我的翻譯中,我假設您有以下內容:

class Certificate
{
    // Other properties ...
    public ICollection<TrainingSchedule> TrainingSchedules { get; set; }  
    public ICollection<Registration> Registrations { get; set; }  
}

class TrainingSchedule
{
    // Other properties ...
    public Certificate Certificate { get; set; }  
}

class Registration
{
    // Other properties ...
    public Certificate Certificate { get; set; }  
}

更新:這與查詢語法相同:

var train = 
    from c in db.Certificates
    where c.Year.Value.Year == year && 
          c.TrainingTypeId.Value == trainingTypeId &&
          c.IsApproved.Value &&
          c.TrainingSchedules.Any(ts => ts.EndDate >= DateTime.Now) &&
          !c.Registrations.Any(r => r.EmployeeId == empId)
    select c;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM