views:

314

answers:

2

Hi, 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,
               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.

+1  A: 

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.

Patrick Karcher
So for every complex query i write do I have to write a custom class from that?
Soham Dasgupta
No. The starting point is a different repository class for each entity. You might have 1 "select" method, you might have 8. Ideally your "select" methods take some parameters at least to ensure that queries will be at least partially based on an indexed field. For a discussion of balancing how many methods to have, see: http://stackoverflow.com/questions/2849873/2849944#2849944
Patrick Karcher
+1  A: 
jslatts