views:

60

answers:

1

I use Framework Entity 4 in my project. I would like to create a function that will return an Expression Nothing seem to work. I get this Internal .Net Framework Data Provider error 1025.

Here is my Expression Method

   public Expression<Func<SupplierTypeText, bool>> GetLmbLang()
   {
       return (p => p.LangID == 1);
   }

I call the GetLmbLang method and get an error.

var ViewModel = _db.Suppliers.Select(model => new {
                model,
                SupType = model.SupplierType.SupplierTypeTexts.Where(repBase.GetLmbLang().Compile())
            });

            Response.Write("<pre>");
            Response.Write(((ObjectQuery)ViewModel).ToTraceString());
            Response.Write("</pre>");

If I write the expression directly in the WHERE clause , there is no problem.

var ViewModel = _db.Suppliers.Select(model => new {
                model,
                SupType = model.SupplierType.SupplierTypeTexts.Where(p => p.LangID == 1)
            });

Thanks.

+1  A: 

That's because you invoke Compile Method on your expression and you don't need to. You should just pass repBase.GetLmbLang() as the predicate to the Where method like this:

SupType = model.SupplierType.SupplierTypeTexts.Where(repBase.GetLmbLang())


EDIT:
I think you've misunderstood a little about when you should use Expression<Func<SupplierTypeText, bool>> and when only Func<SupplierTypeText, bool>.

Basically when you invoke Where method on model.SupplierType.SupplierTypeTexts you are calling Enumerable.Where Method with this signature (LINQ to Objects):

public static IEnumerable<TSource> Where<TSource>(
        this IEnumerable<TSource> source,
        Func<TSource, bool> predicate
)

But, by providing Expression<Func<SupplierTypeText, bool>> you actually meant Queryable.Where which has this signature (LINQ to Entities):

public static IQueryable<TSource> Where(
        this IQueryable<TSource> source,
        Expression<Func<TSource, bool>> predicate
)

Now what happened there is that when you code model.SupplierType.SupplierTypeTexts.Where(repBase.GetLmbLang()) SupplierTypeTexts is populating from database by lazy loading and become a ready EntityCollection in memory for you to query so your first solution is to change the GetLmbLang() method accordingly:

public Func<SupplierTypeText, bool> GetLmbLang() {
       return (p => p.LangID == 1);
}

and then call it like this inside your anonymous class:

SupType = model.SupplierType.SupplierTypeTexts.Where(repBase.GetLmbLang())

Your second solution would be to keep the GetLmbLang() method as it is now and actually change the way you create SupType:

var ViewModel = _db.Suppliers.Select(model => new {
                model,
                SupType = _db.SupplierTypeTexts
                             .Where(repBase.GetLmbLang())
            });


A Note on Provider Error 1205:
This exception happens only when you are doing a projection with anonymous types and passing an Expression<Func<...>> inside like the code below:

var ViewModel = _db.Suppliers.Select(model => new {
        SupType = _db.SupplierTypeTexts.Where(repBase.GetLmbLang())
});

If you remove the projection with anonymous type or if you keep the projection and get rid of the method that returns Expression<Func<...>> it will go away. Why this happens? I have no idea, it sounds like a provider bug to me. But one thing for sure is that theoretically it should works and there is absolutely nothing wrong with this code. That being said, feel free to start a new question and see what other guys have to say.
If you want to do so, then your question title should be something like this: Why am I getting Provider Error 1205 exception when I try to do a projection with anonymous type while passing in an Expression<Func<...>>?

Morteza Manavi
mmm, I Try that, and it dosen't work.
Jean-Francois
I Got the same error.
Jean-Francois
Please check out my edited answer.
Morteza Manavi
@Morteza, Very clean and usefull explanation as you always do. Thanks. One last thing. Why when I want to trace the SQL Query result with Response.Write(((ObjectQuery)ViewModel).ToTraceString()); I got this error.Internal .NET Framework Data Provider error 1025. I would like to see the generated sql query.
Jean-Francois
I have this error with both solution.
Jean-Francois
No problem, please see my note on this above.
Morteza Manavi