rungus2
rungus2

Reputation: 337

C# Linq query as a function parameter

I am using linq to get some data from my database. When query is empty I want to throw an exception.

public class LinqDataBaseConnector : IDataBaseConnector
{
    public LinqDatabaseDataContext dataContext;

    public User getUser(string login, string password)
    {
        var query = (from c in dataContext.Users
                     where c.username == login && c.password == password
                     select c);

        if (query.Any())
        {
            return query.First();
        }
        else
        {
            throw new NullReferenceException("Empty query!");
        }
    }

    public HardwareConfiguration getHardwareConfiguration(int id)
    {
        var query = (from c in dataContext.HardwareConfigurations
                     where c.ID == id
                     select c);

        if (query.Any())
        {
            return query.First();
        }
        else
        {
            throw new NullReferenceException("Empty query!");
        }
    }
}

How to extract this if/else to ONE private method. Do I need to implement IQueryable<T> interface ?

Upvotes: 2

Views: 128

Answers (4)

PiotrWolkowski
PiotrWolkowski

Reputation: 8782

Is there any reason why you cannot implement it as an extension method:

public static class Extensions
{
    public static T GetFirstOrException<T>(this IEnumerable<T> myList)
    {
        if (myList.Any())
        {
            return myList.First();
        }
        else
        {
            throw new NullReferenceException("Empty query!");
        }
    }
}

In both cases you can then use the extension method:

public User getUser(string login, string password)
{
    var query = (from c in dataContext.Users
                 where c.username == login && c.password == password
                 select c);

    return query.GetFirstOrException();
}

public HardwareConfiguration getHardwareConfiguration(int id)
{
    var query = (from c in dataContext.HardwareConfigurations
                 where c.ID == id
                 select c);

    return query.GetFirstOrException();
}

Upvotes: 0

John HardCash
John HardCash

Reputation: 29

Why not

    var query = (from c in dataContext.Users
                 where c.username == login && c.password == password
                 select c).FirstOrDefault();

    if (query!=null)
    {
        return query;
    }
    else
    {
        throw new NullReferenceException("Empty query!");
    }

Upvotes: 0

Marko
Marko

Reputation: 2734

Simplified code below. Also i do hope you have some password hashing and not just plain text.

public class LinqDataBaseConnector : IDataBaseConnector
{
    #region Private Variables
    public LinqDatabaseDataContext dataContext;
    #endregion

    public User getUser(string login, string password)
    {   
        return this.dataContext.Users.First(x => x.username == login && x.password == password);
    }

    public HardwareConfiguration getHardwareConfiguration(int id)
    {   
        return this.dataContext.HardwareConfigurations.First(x => x.ID == id);
    }
}

Upvotes: 1

Servy
Servy

Reputation: 203812

Don't call Any, just call First. It will throw an exception if the query has no items, which is exactly what you want. There's no need to create another operator as First already has the appropriate semantics.

In addition to just being easier, it results in the database query being executed just once, rather than twice.

Upvotes: 8

Related Questions