1

So I posted this earlier.: IAsyncRepository or IObservableRepository for silverlight 4 + WCF Data Services

I've been working on an AsyncRepo for Silverlight so I've just got stuck at a small place.

The code is just for the explanation...scroll to bottom for the culprit code.

I have a repo defined like this:

public interface IAsyncRepository<T> where T : class
{
    void GetById(int id, Action<T> callback);
    void GetAllFromQuery(Func<MyEntities, IQueryable<Product>> funcquery, Action<IList<Calculator>> callback)
}

I'm using WCF Data Services + Linq to Entities. The first one works perfect like this:

    public void GetById(int id, Action<Product> callback)
    {
        MyEntities dat = new MyEntities(new Uri(..url..));
        var query = from c in dat.Products where c.ID == id select c;//WATCH THIS
        allQuery = new DataServiceCollection<Product>(dat);
        allQuery.LoadAsync(query);
        allQuery.LoadCompleted += (obj, evt) =>
            {
                if (allQuery == null)
                {
                    callback(null);
                }
                else
                {
                    callback(allQuery.FirstOrDefault());
                }
            };
    }

Now to the second method:

If you notice in the above method, I have a linq query I use to get the data. In my second repo method, I want to pass this query from the consumer into the method.

So now..

    public void GetAllFromQuery(Func<MyEntities, IQueryable<Product>> funcquery, Action<IList<Product>> callback)
    {
        MyEntities dat = new MyEntities(..uri..);
        allQuery = new DataServiceCollection<Product>(dat);
        allQuery.LoadAsync(funcquery(dat));
        allQuery.LoadCompleted += (obj, evt) =>
        {
            if (allCalcQuery == null)
            {
                callback(null);
            }
            else
            {
                callback(allQuery.ToList());
            }
        };
    }

No problem so far... until...

I use it like this:

        repo.GetAllFromQuery(
            x => from p in x.Products where p.ID > 5 select p,
            y => Assert.IsTrue(y.Count > 0));

This gives me :

cannot convert from 'lambda expression' to System.Func<MyEntities,IQueryable<Product.Calculator>>'

I will truly respect someone who gives me any solution. This has given me programmers block all day today!

Community
  • 1
  • 1
gideon
  • 19,329
  • 11
  • 72
  • 113

1 Answers1

4

EDIT: Okay, now the typo's fixed, try the non-query version (which I think is simpler anyway):

repo.GetAllFromQuery(
    x => x.Products.Where(p => p.ID > 5),
    y => Assert.IsTrue(y.Count > 0));
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • arg! Sorry.. thats a simplification gone wrong... typo fixed. When I hover `p` in visual studio it gives me `? range variable` as opposed to smartly figuring out the type. – gideon Mar 18 '11 at 15:06
  • @giddy: What's the type of MyEntities.Products? Does the non-query version work? – Jon Skeet Mar 18 '11 at 15:10
  • Nope! No luck yet. When I type x.Products.. I get intellisense till there.. after that intellisense goes for a toss. But nope. Still give me the same error. Am I mucking the types.. or defining something wrong.. – gideon Mar 18 '11 at 15:12
  • @giddy: Are you missing `using System.Linq;` at the top of the file containing this code? What's the error message when you try to compile the non-query version? – Jon Skeet Mar 18 '11 at 15:13
  • @jon yes. I do have `System.Ling` ....Error **(1)** Invalid argument... **(2)** Cannot convert lambda expression to.... (same error as before no change) Could it be that this call is within a Silverlight **Test** app and I don't have a reference to Entity Framework – gideon Mar 18 '11 at 15:15
  • @giddy: I've just realized that your `GetAllFromQuery` first argument is meant to be an `IQueryable`, not a delegate at all. Are you sure the signature you've posted is correct? It doesn't make sense with the error message you've included. – Jon Skeet Mar 18 '11 at 15:17
  • @jon jeez sorry...that was the interface.. sorry..fixed.. I tried simpifying the code because my real entity name (`Product`) and entity model (`MyEntites`) are seriously long names.. thats all I've basically changed from my code. – gideon Mar 18 '11 at 15:22
  • @giddy: Okay, that makes a bit more sense. You'll need a reference to the entity framework if your `MyEntities.Products` refers to a type within EF, yes. When you say "invalid argument" could you give the *exact* error message please? – Jon Skeet Mar 18 '11 at 15:24
  • Ah! Omg! I ran your code inside the beast of the main silverlight application itself.. it runs.. after that.. when I build the test application.. it gives me another set of errors.. missing `System.Data.Services.Client` .. added as a reference! **It works** =S! Sorry! I really thought I was doing something wrong with linq! – gideon Mar 18 '11 at 15:34
  • @jon Also, since you're here. Do you think the design is ok or screaming horrible. I think it does solve my problem of dealing with the madness of BeginEvent.. EndEvent... – gideon Mar 18 '11 at 15:35
  • @giddy: I'm not sure about the null handling, but apart from that, it depends what you're trying to do really. You'll still need to deal with the asynchrony elsewhere... – Jon Skeet Mar 18 '11 at 15:37
  • @Jon I'm mainly trying to **(1)** cleanly encapsulate the asynchrony stuff...so there is a common way to perform CRUD operations on each entity from ViewModels. **(2)** load child entities..since they need need the parent entity first.. so I will load all related entities and then call the callback. – gideon Mar 18 '11 at 15:43
  • @jon thanks a million! =D I finally came up with a Repository Pattern that uses observables (in the linked Q) and it works quite well. – gideon Mar 19 '11 at 19:19