Linq - 优化/更正我的查询

时间:2012-01-31 11:59:03

标签: c# linq

我有这个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();
    }

3 个答案:

答案 0 :(得分:1)

我假设OfficePostCodeOffice都有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")));