1

I've been working on a project which uses a third-party DAL (SubSonic) to produce classes for all database objects.

For querying those objects, the existing code practice has generally been:

int keyValue = 1;
TableObject t = TableObject.SingleOrDefault(x => (x.keyField == keyValue));
if (t != null) {
    int valueWeWant = t.fieldWeWant;
    string otherValueWeWant = t.otherFieldWeWant;
}

I've been generally trying to reduce the SQL traffic as much as possible, since we tend to have large rows and are often only concerned with one or two fields. So far the best approach I've been able to find is:

int keyValue = 1;
var t = TableObject.All().Where(x => (x.keyField == keyValue)).Select(x => new { x.fieldWeWant, x.otherFieldWeWant}).Take(1);
if ((t != null) && (t.Count() != 0)) {
    int valueWeWant = t.First().fieldWeWant;
    string otherValueWeWant = t.First().otherFieldWeWant;
}

I like that the generated SQL is only selecting a single row and 2 fields, and am happy with the readability of the anonymous type, but having to compare .Count() seems wasteful to me.

Am I missing a simpler way to perform this?

4

2 に答える 2

3

If you replace Take(1) with SingleOrDefault(), you would need to check only for null, not for the Count() == 1, and skip the call of First():

var t = TableObject
    .All()
    .Where(x => (x.keyField == keyValue))
    .Select(x => new { x.fieldWeWant, x.otherFieldWeWant})
    .SingleOrDefault();
if (t != null) {
    int valueWeWant = t.fieldWeWant;
    string otherValueWeWant = t.otherFieldWeWant;
}
于 2012-11-09T20:06:38.133 に答える
0

You have the right idea but if you find yourslef using Count() > 0, you will want to use

if ((t != null) && (t.Any())) 

.Any() returns true once it finds the first entity in the collection. Whereas, .Count() iterates the entire collection before returning true and is a performance hit

于 2012-11-09T20:04:49.923 に答える