我有这个linq查询(不确定它是否正确)但我想要的是:
把我所有的公司办公室(与我的公司有关,例如companyid == mycompanyid) 已宣布他们有邮政编码“cv”,只返回办公室。 (代码为清晰起见)
var offices = from office in _readOnlySession.All<Office>()
.GetMyOffices(_userSession) //filter out my offices using extension method
let postcodes = _readOnlySession.All<OfficePostCode>().Where(x => x.OfficeID == office.OfficeID)
.Join(_readOnlySession.All<PostCodeDistrict>().Where(r=> r.Region.ToLower().StartsWith("cv".ToLower())),
x => x.PostCodeID,
y => y.PostCodeID,
(x, y) => new { Region = y.Region })
where postcodes.Any()
select new { office.OfficeID, office.Name };
问题:如何将这一切都作为一种查询方法,一种更优化/更正确的查询方法?
注意:“cv”将成为传递给方法的变量 - 有点硬编码来说明我的例子
更新
IQueryable<T> All<T>() where T : class, new();
public IQueryable<T> All<T>() where T : class, new()
{
return GetTable<T>().AsQueryable();
}
答案 0 :(得分:1)
我假设OfficePostCode
和Office
都有PostCodeID
个属性,您可能需要更改最后一个.Where()
子句以适合您拥有的属性。这应该做你想要的,IMO更容易阅读。
public IEnumerable<Office> GetOffices (string postCode)
{
List<Office> myOffices = _readOnlySession.All<Office> ()
.GetMyOffices (_userSession)
.ToList (); // Get all the offices you are interested in.
List<OfficePostCode> postCodeDistricts = _readOnlySession
.All<OfficePostCode> ()
.Where (x => x.Region.StartsWith (postCode, true, System.Globalization.CultureInfo.InvariantCulture))
.ToList (); // A list of OfficePostCodes with the specified region.
// Using the 3 parameter overload for StartsWith lets you specify a case invariant comparison,
// which saves you from having to do .ToLower().
return myOffices.Where (o => postCodeDistricts.Any (pcd => o.PostCodeID == pcd.PostCodeID));
}
当然,你可以通过删除中间变量来压缩它,但我个人觉得这样更清楚。它还使调试更容易,因为您可以在中间变量上放置断点。
答案 1 :(得分:0)
似乎没问题。只有能够但不能更好地工作的是在主查询之前执行 let postcodes 部分而没有OfficeID条件,然后在主查询中使用它,如:
where postcodes.Any(pc => pc.OfficeID == office.OfficeID)
答案 2 :(得分:0)
这样的事可能吗?
var offices = _readOnlySession.All<Office>()
.GetMyOffices(_userSession) //filter out my offices using extension method
.Where(office => office.PostCodes.Any(pc => pc.District.Region.ToUpperInvariant().StartsWith("CV")));