1

I have made myself an ExpressionBuilder class that helps me put together expressions that can be used as a predicate when doing Linq to Sql queries. It has worked great. However, I just discovered Expressions can only be used to filter on Tables, and not on EntitySets??Why on earth is this the case?

For example if I have Company and an Employee with a Salary. I could create these two expressions:

Expression<Func<Company, bool>> cp = x => x.Name.StartsWith("Micro");
Expression<Func<Employee, bool>> ep = x => x.Name.StartsWith("John");

I would then expect to be able to do the following, however it only partially works:

var companies = dataContext.Companies
    .Where(cp)                                // Goes fine
    .Select(x => new 
        {
            x.Name,
            SumOfSalaries = x.Employees
                .Where(ep)                    // Causes compile-time error
                .Sum(y => y.Salary),
        }
    .ToList();

Also, if I do a ep.Compile() it compiles, but then I get an error when running the query.

Why is this the case? Am I missing something? I don't find this logical. Can I fix this somehow? Or do you have a good workaround?

I know that I in this case could just use Where(x => x.Name.StartsWith("John")) instead, but the problem is that the expressions I need are not that trivial. They are longer strings of AndAlsos and OrElses.

4

3 に答える 3

0

ラムダ式を LINQ to SQL プロバイダーに渡す場合は、それを として作成しないExpression<T>でください。プロバイダーに任せてください。

于 2009-09-30T13:55:01.043 に答える
0

以下は私にとってはうまくいきます -両方がコンパイルされていることに注意してください:

var companies = dataContext.Companies.Where(cp.Compile())
                .Select(x => new
                                 {
                                     x.Name,
                                     SumOfSalaries = x.Employees
                                        .Where( ep.Compile() )
                                        .Sum(y => y.Salary),
                                 }

                 ).ToList();

式パーサーは、2 番目の where 句を挿入すると、最初の where 句の後のどこかで型情報を失っているようです。正直なところ、まだ理由はわかりません。

編集: 明確にするために、EntitySet は式を where 句に渡すことをサポートしていないことを理解しています私が完全に理解していないのは、Where(ep.Compile()) を追加すると失敗する理由です。
私の理論では、最初の where (Where(cp.Compile()) をコンパイルする際に、Linq2Sql は式の解析を終了します。エンティティセットに対して ep.Compile() を解析できず、分割することを決定できません。最初の where 句をコンパイルするまで、クエリを 2 つに分割します。

于 2009-09-30T14:48:27.350 に答える
0

クエリを書き直す必要があると思います。必要な詳細を尋ねる別の方法は、次のとおりです。

したがって、従業員の給与に焦点を当てると、次のように書くことができます。

    //Expression<Func<Employee, bool>> ep = x => x.Name.StartsWith("John");
    //Expression<Func<Company, bool>> cp = x => x.Name.StartsWith("Micro");

    Expression<Func<Employee, bool>> ep = x => x.Name.StartsWith("John");
    Expression<Func<Employee, bool>> cp = x => x.Company.Name.StartsWith("Micro");

    var salaryByCompany = dataContext.Employees
        .Where(ep)
        .Where(cp)
        .GroupBy(employee => employee.Company.Name)
        .Select(companyEmployees => new
                                        {
                                            Name = companyEmployees.Key,
                                            SumOfSalaries = companyEmployees.Sum(employee => employee.Salary)
                                        });

    var companies = salaryByCompany.ToList();
于 2009-10-12T12:39:58.700 に答える