[英]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
,那么什么是Linq
, Lambda
是fluent
的Linq
表示的組成部分,因為大多數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 the
的fluent' 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
,分別引用Certificate
和Training Schedule
類 new { a, b }
,而不是像CerificateTrainingSchedule
這樣創建一個class
,該類分別具有Certificate
和Training 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表達式甚至可以使用相同的變量名。
請注意,在查詢表達式語法中,並非所有變量都“成功”。 特別是,我們丟失了z
和t
因為這些變量是多余的。
在這么長時間的表達式中,可能會發現較長的變量名很有用。 但這是一個權衡。 查詢表達語言旨在提供一種表示數據源查詢的緊湊方式。 較長的變量名可能會使得更難理解查詢本身,即使它可能使更容易理解表達式的各個部分的意圖也是如此。 這很大程度上取決於個人喜好。
我看不到復雜的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 TrainingSchedules
和Any
“ Registrations
), 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.