How to create anonymous objects of type IQueryable using LINQ
I'm working in an ASP.NET MVC project where I have created a two LinqToSQL classes. I have also created a repository class for the models and I've implemented some methods like LIST, ADD, SAVE in that class which serves the controller with data. Now in one of the repository classes I have pulled some data with LINQ joins like this.
private HerculesCompanyDataContext Company = new HerculesCompanyDataContext();
private HerculesMainDataContext MasterData = new HerculesMainDataContext();
public IQueryable TRFLIST()
{
var info = from trfTable in Company.TRFs
join exusrTable in MasterData.ex_users on trfTable.P_ID equals exusrTable.EXUSER
select new
{
trfTable.REQ_NO,
trfTable.REQ_DATE,
exusrTable.USER_NAME,
exusrTable.USER_LNAME,
trfTable.FROM_DT,
trfTable.TO_DT,
开发者_StackOverflow中文版 trfTable.DESTN,
trfTable.TRAIN,
trfTable.CAR,
trfTable.AIRPLANE,
trfTable.TAXI,
trfTable.TPURPOSE,
trfTable.STAT,
trfTable.ROUTING
};
return info;
}
Now when I call this method from my controller I'm unable to get a list. What I want to know is without creating a custom data model class how can I return an object of anonymous type like IQueryable. And because this does not belong to any one data model how can refer to this list in the view.
You cannot return an object of "anonymous type". Please see this previous post of mine that address this situation, where it seems anonymous types will allow us to cheat a little bit on strong typing, but they do not.
Yes, moving from flexible types (like DataTables) to strongly typed objects is a huge part of your solution strategy. With LINQ-To-SQL, you should be able to pretty easily get back strongly typed entity objects. Your repository methods need to return specifically typed IQueryable interfaces,like IQueryable<TRF>
, not just IQueryable
. Or, a repository method could just return a single TRF
entity object, or a list of these objects.
Keep in mind that anonymous types and implicitly typed variables are two very different things. An anonymous type is created for you by the compiler behind the scenes. In this case, don't put your data into an anonymous type, like you do in your example LINQ query. Assuming your entity is trfTable, try this:
public IQueryable<trfTable> TRFLIST()
{
var info = from trfTable in Company.TRFs
join exusrTable in MasterData.ex_users on trfTable.P_ID equals exusrTable.EXUSER
select new trfTable
return info;
}
The benefit of this is that it takes massive advantage of the nature of IQueryable, in that criteria added outside your repository will actually be added to the generated query. It's cool. However, there is some good debate about whether this is the best way to do it.
Note that info
here is implicitly typed by the compiler, but it is not an anonymous type. It is an IQuerable<trfTable>
. This is the key distinction.
You can sort of return an anonymous type, just not in a way that is strongly typed. I use this method to create json-serializable types.
Return a type of "object" in your data model class:
public object TRFLIST()
{
var info = from trfTable in Company.TRFs
join exusrTable in MasterData.ex_users on trfTable.P_ID equals exusrTable.EXUSER
select new
{
trfTable.REQ_NO,
trfTable.REQ_DATE,
exusrTable.USER_NAME,
exusrTable.USER_LNAME,
trfTable.FROM_DT,
<snipped>
};
return info;
}
Then call it from your controller like this (in this example, I am using it to return a JsonResult):
public JsonResult() {
var myAnonTRFLIST = dataClassInstance.TRFLIST();
return Json(myAnonTRFLIST, JsonRequestBehavior.Allowget);
}
You could also explore using the new dynamic type if you are in 4.0...
-UPDATE: I just tried this out and it worked perfectly-
Return a type of "object" in your data model class:
public List<object> TRFLIST()
{
var info = from trfTable in Company.TRFs
join exusrTable in MasterData.ex_users on trfTable.P_ID equals exusrTable.EXUSER
select new
{
trfTable.REQ_NO,
trfTable.REQ_DATE,
exusrTable.USER_NAME,
exusrTable.USER_LNAME,
trfTable.FROM_DT,
<snipped>
};
return info.ToList<object>();
}
public JsonResult() {
dynamic myAnonTRFLIST = dataClassInstance.TRFLIST();
string test = myAnonTRFLIST[0].USER_NAME;
<Do something with Test>
return Json(myAnonTRFLIST, JsonRequestBehavior.Allowget);
}
精彩评论