Using an indexer to retrieve a Linq to SQL object from a data store

class UserDatastore : IUserDatastore
{
    ...

    public IUser this[Guid userId]
    {
        get
        {
            User user = (from u in _dataContext.Users
                             where u.Id == userId
                             select u).FirstOrDefault();

            return user;
        }
    }

    ...
}

      

One of the developers on our team claims that an index is not suitable in the above situation and that the method should be used GetUser(Guid id)

.

The arguments are as follows:

1) We are not indexing into an in-memory collection, the indexer is basically doing a hidden SQL query 2) Using the pointer in the indexer is bad (FxCop also noted this) 3) Returning null

from the indexer is not normal behavior 4) The API user did not usually expect this behavior

I agree that (in most) of these points.

But I am also inclined to argue that one of the characteristics of Linq is abstraction of the database access to make it seem like you are just working with many collections, although the lazy evaluation paradigm means that these collections aren't evaluated as long as you don't run a query on them. It doesn't seem inconsistent to me to access the data store in the same way as if it were a specific collection in memory.

Also, bearing in mind that it is a legacy codebase that uses this pattern extensively and consistently, is refactoring worth it? I agree that it would have been better to use the Get method from the start, but I am not yet convinced that it is completely wrong to use an indexer.

I would be interested to hear all the opinions, thanks.

+2


a source to share


2 answers


I tend to agree with pretty much everything your developer team has suggested except for a part Guid

. If there is a problem here, it should be at the database level, considering performance, not code.

Personally, I believe that properties and indexes should not hide lengthy operations, although Users

LINQ-to-SQL can be cached. Therefore, I would also prefer the method.



I also agree that returning null from the indexer is bad. Choose an exception instead.

0


a source


I think his point of view on using a GUID as an indexer is probably due to the fact that it is stored in the database. Using an integer as the key would provide better performance and consume less memory than using a GUID.

Returning null is pretty rare, as usual with an index, if the index (key) is not present in the collection, you threw an exception instead.

Personally I don't really see the problem here, it is pretty much equivalent to the method GetUser

. I mean, if you want to teach it a bit, you could introduce a private method called GetUser

that can call a pointer, for example.



public IUser this[Guid userId]
{
    get { return GetUser(userId); }
}

private IUser GetUser(Guid userId)
{
    return (from u in _dataContext.Users 
            where u.Id == userId 
            select u).FirstOrDefault();
}

      

From a design perspective, I personally would not use Indexer, I would go with the method GetUser

.

0


a source







All Articles