Reputation: 3472
I have this linq query (not sure if its correct) but what I want is:
Get me all my company offices (that are related to my company e.g. companyid == mycompanyid) that have declared they have postcode "cv", return back only offices. (code for clarity)
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 };
Question: how can I make this all a query method, a more optimized/correct query method?
Note: "cv" is going to be a variable passed into the method - kinda hardcoded to illustrate my example
Update:
IQueryable<T> All<T>() where T : class, new();
public IQueryable<T> All<T>() where T : class, new()
{
return GetTable<T>().AsQueryable();
}
Upvotes: 0
Views: 126
Reputation: 342
I've assumed that OfficePostCode
and Office
both have PostCodeID
properties, you might need to change the last .Where()
clause to fit the properties you have. This should do what you want though, and IMO is a bit easier to read.
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));
}
Of course, you can compact this down by removing the intermediate variables, but I personally find it clearer this way. It makes debugging easier as well, as you can put breakpoints on the intermediate variables.
Upvotes: 1
Reputation: 385
Something like this maybe?
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")));
Upvotes: 0
Reputation: 620
It seems to be OK. Only what can but also cannot work better is to execute let postcodes part without OfficeID condition before main query and then use it in main query like:
where postcodes.Any(pc => pc.OfficeID == office.OfficeID)
Upvotes: 0