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>
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: