0

I'm using mvc 5 and wanna define extension method FindMessageAsync in class Queryable (namespace System.Linq).

I usually use this way to get some records in database:

public void GetMessage(string id)
{
  using (var db = new MyDbContext())
  {    
    var message = db.Message.FirstOrDefault(x => x.Id == id);
    //or
    var _message = db.Message.Where(x => x.Id == id).ToList();

    //do stuff
  }
}

I wanna improve the method to:

public async Task<MessageViewModels> GetMessage(string id)
{
  using (var db = new MyDbContext())
  {    
    var message = await db.Message.FindMessageAsync(x => x.Id == id);

    if (message != null)
    {
      //string id = message.Id;
      //string fromUser = message.FromUser;
      //string toUser = message.ToUser;
      //string content = message.Content;
      //bool isRead = message.IsRead;
    }

    //do stuff
  }
}

My question is: How to define extension method FindMessageAsync?

UPDATE:

The answers of this question don't solve my problem.

Community
  • 1
  • 1
Tân
  • 1
  • 15
  • 56
  • 102
  • Do you think this should be an `IQueryable` extension method? Seems to me that it is very specific to your domain model. – Yuval Itzchakov Dec 02 '15 at 08:57
  • @DannyChen Please re-open my question. It's not duplicate. – Tân Dec 02 '15 at 09:03
  • @YuvalItzchakov ya. Class `Queryable` contains `IQueryable` extension method. – Tân Dec 02 '15 at 09:07
  • @HappyCoding Your questions are not exactly the same, but the answers (not only the acccepted answer) in the link answer yours. – Cheng Chen Dec 02 '15 at 09:10
  • @HappyCoding If you just want a simple extension method for `IQueryable`, see [MSDN](https://msdn.microsoft.com/en-us/library/bb383977.aspx). The location of the extension method doesn't matter, you don't have to put it in `Queryable` class. – Cheng Chen Dec 02 '15 at 09:12
  • @DannyChen Do you see lambda expression in the extension method? I wanna use it as a parameter what all the answers of that question didn't talk about. – Tân Dec 02 '15 at 09:15

2 Answers2

1
public static class MyQueryableExtensions {
    public static Task<T> FindMessageAsync<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate) {
        if(source == null) {
            throw new ArgumentNullException("source");
        }
        // Or whatever...
        return source.FirstOrDefault(predicate);
    }
}

The important things are that your method is defined within a static class, that your method is declared static and that the first parameter has the this modifier. It does not matter where exactly the method lives, as long as it's a static class. It doesn't need to be System.Linq.Queryable.

However, you should think twice as to whether you really want to implement domain-specific logic in extension methods...

Henrik Ilgen
  • 1,879
  • 1
  • 17
  • 35
  • Possible `T` is `MessageViewModels` :) – Tân Dec 02 '15 at 09:36
  • @HappyCoding that can be infered from the usage of the method ;) However, as @Danny Chen said, it's not really necessary to provide a wrapper around `FirstOrDefault`. It **might** make sense to provide additional logic here (while, as I said, there might be better places for that than extension methods). What is your exact use case? – Henrik Ilgen Dec 02 '15 at 09:44
1

If you want a single item, .FirstOrDefault (as well as related methods like First Single) is the best choice, it's really unnecessary to implement another extension method and wrap it.

If you want a list asynchronously, probably you want .ToListAsync method.

Cheng Chen
  • 42,509
  • 16
  • 113
  • 174
  • Yup. `await db.Message.Where(x => x.Id == id).ToListAsync()` = `await db.Message.FindMessageAsync(x => x.Id == id)` – Tân Dec 02 '15 at 09:54