Asp.net mvc 2 为什么当我传递Lambda expressin Func时,这会给我一个错误

Asp.net mvc 2 为什么当我传递Lambda expressin Func时,这会给我一个错误,asp.net-mvc-2,entity-framework-4,lambda,Asp.net Mvc 2,Entity Framework 4,Lambda,当我传递调用一个返回Func的泛型方法并传入Where参数时,这是行不通的。System.InvalidOperationException:内部.NET Framework数据提供程序错误1025。 错误是当我想要获取角色信息时。 对于角色,我需要执行Where子句表达式EX:p=>p.LangID==1 这个代码不起作用 在存储库中 public Func<T, bool> GetLmbLang<T>() where T:class,IBaseGenericTxt

当我传递调用一个返回Func的泛型方法并传入Where参数时,这是行不通的。System.InvalidOperationException:内部.NET Framework数据提供程序错误1025。 错误是当我想要获取角色信息时。 对于角色,我需要执行Where子句表达式EX:p=>p.LangID==1

这个代码不起作用

在存储库中

public Func<T, bool> GetLmbLang<T>() where T:class,IBaseGenericTxt
    {
        int lang = -1;
        lang = Convert.ToInt32(HttpContext.Current.Session["Language"]);
        return (p => p.LangID == lang);
    }
我的列表视图


后一段代码之所以有效,是因为C编译器将其转换为表达式树,即System.Linq.expression,而您的原始代码是作为Func编译的。当前设计的Linq to SQL无法处理Func,只能处理表达式树。

正如naasking指出的,您需要使用Func的表达式而不是直Func:

public Expression<Func<T, bool>> GetLmbLang<T>() where T:class,IBaseGenericTxt
{
    int lang = -1;
    lang = Convert.ToInt32(HttpContext.Current.Session["Language"]);
    return (p => p.LangID == lang);
}
编辑2

两件事:

因为LINQ到实体将尝试在查询表达式中取任何东西并将其转换为SQL语句,所以必须小心不要在查询的中间调用方法。您需要首先调用GetLmbLang方法,并将其值存储在查询中使用的变量中。 正如您在评论中指出的,因为ContactTypeText属性没有实现IQueryable,所以这变得特别棘手。据我所知,您有三种选择:

将整个select语句创建为表达式树。这很烦人,而且容易出错。 使用Joe Albari来编译和扩展查询。LinqKit将遍历表达式树并构建一个新的树,在该树中,查询表达式将转换为其等价的Func。 返回数据上下文,而不是使用ContactTypeText属性。 就我个人而言,我可能会选择最后一个选项,比如:

var paramExpr = Expression.Parameter(typeof(T), "p");
return Expression.Lambda<Func<T, bool>>(
    Expression.Equal(
        Expression.Property(paramExpr, "LangId"),
        Expression.Constant(lang)),
    paramExpr);
var lambdaLang = repGeneric.GetLmbLang<ContactTypeText>();
var ViewModel = _db.Contacts
    .Where(a=> a.IsActive == true)
    .Select(a => new ContactListViewModel { 
    ContactID = a.ContactID,
    ContactName = a.ContactName,
    Role = _db.ContactTypeTexts
        .Where(ct => ct.ContactType.Contacts.Any(
            c => c.ContactId == a.ContactId)
        .Where(lambdaLang)
        .Select(af => af.Txt).FirstOrDefault(),
    CompanyType = a.Supplier.SupplierName,
    Addr = a.Address ,
    Email = a.ContactEmail,
    Phone = a.ContactPhone
}).ToList();

非常混乱的代码。doing _db.Contacts.ToList基本上抓取所有联系人,然后在联系人处于活动状态时对其执行另一个查询,执行AsQueryable,这是多余的,但我认为主要问题是您试图在投影(即角色属性)中执行内联查询。也许如果你解释一下你想做什么,我们可以帮你写一个更好的查询。我想用我所有的活跃联系人填写一个表格。关于AsQueryable你是对的。我做了很多测试,只是忘了在我的帖子中删除它。角色是字符串,我需要从联系人类型文本中获取此值。我将对我的原始帖子进行更新,添加detailsOk,我尝试了一下,但这会给我两个错误。错误1实例参数:无法从“System.Data.Objects.DataClasses.EntityCollection”转换为“System.Linq.IQueryable”C:\inetpub\wwwroot\myproject\myproject\Controllers\ContactController.cs 35 24 myprojectseconde一个是:错误2的“System.Data.Objects.DataClasses.EntityCollection”未包含“Where”和最佳值的定义扩展方法重载“System.Linq.Queryable.WhereSystem.Linq.IQueryable,System.Linq.Expressions.Expression”具有一些无效参数C:\inetpub\wwwroot\myproject\myproject\Controllers\ContactController.cs 35 24myproject@Jean-弗朗索瓦:好的,我明白你的意思,但那不起作用。出现此问题是因为我对ContactTypeText进行了子查询。如果我直接在实体上应用函数,比如_db.contacttypetext.WhererepGeneric.GetLmbLang,这就是工作。如果我在Select中执行相同的操作,如_db.Contacts.Selecta=>new{SingleContactType=a.ContactType.ContactTypeTexts.WhererepGeneric.GetLmbLang},则会失败。。谢谢你的好意@StriplingWarrior@StriplingWarrior. 谢谢你的帮助。很好的解释。在这个问题上,我付出了很多努力来支持我。我真的很感激你在这里所做的一切。当然,如果我能帮你做点什么,我会尽力帮你的。
 ..... Inherits="System.Web.Mvc.ViewPage<List<mvcinfosite.ViewModels.ContactListViewModel>>" %>
 <table class="genTable">


    <% for (int i = 0;i < Model.Count; i++) { %>
        <tr>
            <td>
                <%: Html.ActionLink(item.ContactName, "Edit", new { id=item.ContactID }) %>
            </td>

            <td>
                <%: item.Role  %>
            </td>

            <td>
                <%: item.Company %>
            </td>

            <td>
                <%: item.CompanyType  %>
            </td>

            <td>
                <%: GlobalHelper.GetAddress(item.Addr) %>
            </td>
            <td>
                <%: item.Email %>
            </td>
            <td>
                <%: item.Phone %>
            </td>
        </tr>

    <% } %>

    </table>
public Expression<Func<T, bool>> GetLmbLang<T>() where T:class,IBaseGenericTxt
{
    int lang = -1;
    lang = Convert.ToInt32(HttpContext.Current.Session["Language"]);
    return (p => p.LangID == lang);
}
var paramExpr = Expression.Parameter(typeof(T), "p");
return Expression.Lambda<Func<T, bool>>(
    Expression.Equal(
        Expression.Property(paramExpr, "LangId"),
        Expression.Constant(lang)),
    paramExpr);
var lambdaLang = repGeneric.GetLmbLang<ContactTypeText>();
var ViewModel = _db.Contacts
    .Where(a=> a.IsActive == true)
    .Select(a => new ContactListViewModel { 
    ContactID = a.ContactID,
    ContactName = a.ContactName,
    Role = _db.ContactTypeTexts
        .Where(ct => ct.ContactType.Contacts.Any(
            c => c.ContactId == a.ContactId)
        .Where(lambdaLang)
        .Select(af => af.Txt).FirstOrDefault(),
    CompanyType = a.Supplier.SupplierName,
    Addr = a.Address ,
    Email = a.ContactEmail,
    Phone = a.ContactPhone
}).ToList();