为什么当我传递 Lambda Expressin Func 时会出现错误
当我通过调用返回 A 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);
}
在控制器中
var ViewModel = _db.Contacts.Where(a=> a.IsActive == true).Select(a => new ContactListViewModel {
ContactID = a.ContactID,
ContactName = a.ContactName,
Role = a.ContactType.ContactTypeTexts.Where(repGeneric.GetLmbLang<ContactTypeText>()).Select(af => af.Txt).FirstOrDefault(),
CompanyType = a.Supplier.SupplierName,
Addr = a.Address ,
Email = a.ContactEmail,
Phone = a.ContactPhone
}).ToList();
for (int i = 0; i < ViewModel.Count(); i++)
{
Response.Write(ViewModel.ElementAt(i).ContactID + "<br />");
}
此代码有效
int lang = -1;
lang = Convert.ToInt32(Session["Language"]);
var ViewModel = _db.Contacts.Where(a=> a.IsActive == true).Select(a => new ContactListViewModel {
ContactID = a.ContactID,
ContactName = a.ContactName,
Role = a.ContactType.ContactTypeTexts.Where(p => p.LangID == lang).Select(af => af.Txt).FirstOrDefault(),
CompanyType = a.Supplier.SupplierName,
Addr = a.Address ,
Email = a.ContactEmail,
Phone = a.ContactPhone
}).ToList();
for (int i = 0; i < ViewModel.Count(); i++)
{
Response.Write(ViewModel.ElementAt(i).ContactID + "<br />");
}
我的ContactListViewModel
public class ContactListViewModel
{
public int ContactID { get; set; }
public string ContactName { get; set; }
public string Role { get; set; }
public string Company { get; set; }
public string CompanyType { get; set; }
public Address Addr { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
我的列表视图
..... 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>
When I pass call a Generic Method that return A Func and pass in parameter of the Where, that's dosen't work. (System.InvalidOperationException: Internal .NET Framework Data Provider error 1025.)
The error is when I want to get the Role information.
For the Role, I need to perform a Where Clause Expression EX: (p => p.LangID == 1)
This code dosen't Work
In the repository
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);
}
In the controller
var ViewModel = _db.Contacts.Where(a=> a.IsActive == true).Select(a => new ContactListViewModel {
ContactID = a.ContactID,
ContactName = a.ContactName,
Role = a.ContactType.ContactTypeTexts.Where(repGeneric.GetLmbLang<ContactTypeText>()).Select(af => af.Txt).FirstOrDefault(),
CompanyType = a.Supplier.SupplierName,
Addr = a.Address ,
Email = a.ContactEmail,
Phone = a.ContactPhone
}).ToList();
for (int i = 0; i < ViewModel.Count(); i++)
{
Response.Write(ViewModel.ElementAt(i).ContactID + "<br />");
}
This code WORK
int lang = -1;
lang = Convert.ToInt32(Session["Language"]);
var ViewModel = _db.Contacts.Where(a=> a.IsActive == true).Select(a => new ContactListViewModel {
ContactID = a.ContactID,
ContactName = a.ContactName,
Role = a.ContactType.ContactTypeTexts.Where(p => p.LangID == lang).Select(af => af.Txt).FirstOrDefault(),
CompanyType = a.Supplier.SupplierName,
Addr = a.Address ,
Email = a.ContactEmail,
Phone = a.ContactPhone
}).ToList();
for (int i = 0; i < ViewModel.Count(); i++)
{
Response.Write(ViewModel.ElementAt(i).ContactID + "<br />");
}
My ContactListViewModel
public class ContactListViewModel
{
public int ContactID { get; set; }
public string ContactName { get; set; }
public string Role { get; set; }
public string Company { get; set; }
public string CompanyType { get; set; }
public Address Addr { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
}
My List View
..... 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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如 naasking 指出的那样,您需要使用 Func 的表达式而不是直接的 Func:
编辑
啊,是的,问题是您的函数实际上并不知道它正在使用哪个类编译时:它只知道它是一个类,并且它实现了 IBaseGenericTxt。因此,当您说
p.LangId
时,表达式的该部分正在调用 IBaseGenericTxt.LangId,而不是 ContactTypeText.LangId。您需要构建自己的表达式树才能使其正常工作。像这样的东西:
编辑 2
两件事:
正如您在评论中指出的那样,因为 ContactTypeTexts 属性没有实现 IQueryable,所以这变得特别棘手。据我所知,您有三个选择:
就我个人而言,我可能会选择最后一个选项,如下所示:
As naasking points out, you need to use an Expression of a Func instead of a straight Func:
Edit
Ah, yes, well the problem is that your function doesn't actually know what class it's working with at compile time: it only knows that it's a class, and it implements IBaseGenericTxt. So when you say
p.LangId
, that part of the expression is calling IBaseGenericTxt.LangId, and not ContactTypeText.LangId.You'll need to build your own expression tree in order to get this to work right. Something like this:
Edit 2
Two things:
As you point out in your comment, because the ContactTypeTexts property does not implement IQueryable, this gets particularly tricky. You have three options as far as I can tell:
Personally, I would probably go with the last option, like this:
后一个代码之所以有效,是因为 C# 编译器将其转换为表达式树,即。 System.Linq.Expression,而您的原始代码被编译为 Func。当前设计的 Linq to SQL 无法处理 Func,只能处理表达式树。
The latter code works because the C# compiler converts it into an expression tree, ie. System.Linq.Expression, whereas your original code was compiled as a Func. Linq to SQL as currently designed cannot process the Func, only expression trees.