Reputation: 1568
i have below Linq query in my code
var query = (from s in dc.UserContacts
join g in dc.EmailRecipientInGroups on s.UserEmailRecipient.RID equals g.RID
join zk in dc.ZeekUsers on s.UserID equals zk.UserId
where s.aspnet_User.LoweredUserName.Equals(strUserName.ToLower())
&& !g.UserEmailRecipientGroup.IsDeleted
&& !s.UserEmailRecipient.IsDeleted
select new { s = s, g = g, zk = zk });
where dc is DataContext for Linq to SQL
there are other two conditions which I need to include in the above query but below line will remain same
select new { s = s, g = g, zk = zk });
I have two create two separate methods for those two conditions. but the final code to generate output is going to be same for all 3 functions and output will be generated from query object.
So I am thinking of writing a new private method which I can call after above line in all 3 functions with query as parameter and get the result instead of duplicating code every time. But from internet i found that var type can not be passed as parameter.
Here is my Intellisense from Visual Studio when I hover mouse over the var
keyword before query word
interface System.Linq.IQueryable<out T>
T is 'a
Anonymous types:
'a is new { usercontact s, EmailRecipientinGroup g, Zeekuser zk}
Upvotes: 0
Views: 1398
Reputation: 14856
As others have already said, "variables that are declared at method scope can have an implicit type var. An implicitly typed local variable is strongly typed just as if you had declared the type yourself, but the compiler determines the type."
It is, however, the only way to declare variables of types that are, or involve, anonymous types.
Now to the LINQ part. You can look at LINQ queries as database view definitions (they are only executed when enumerated) but with a great benefit: they are composable.
You can write something like this:
IQueriable<UserContact> userContactsQuery =
from s in dc.UserContacts
where s.aspnet_User.LoweredUserName.Equals(strUserName.ToLower())
&& !s.UserEmailRecipient.IsDeleted
select s;
IQueriable<EmailRecipientInGroup> emailRecipientInGroupsQuery =
from g in dc.EmailRecipientInGroups
where !g.UserEmailRecipientGroup.IsDeleted
select g;
IQueriable<ZeekUser> zeekUsersQuery =
from z in db.ZeekUsers
select z;
var query = from s in userContactsQuery
join g in emailRecipientInGroupsQuery on s.UserEmailRecipient.RID equals g.RID
join zk in zeekUsersQuery on s.UserID equals zk.UserId
select new { s = s, g = g, zk = zk });
I'd use var
myself but this is only to show that most of your query can be typed.
You might want to consider inserting your other conditions somewhere in the middle of the query instead of the end.
Upvotes: 0
Reputation: 15119
var
as such will be defined as an actual type during runtime and can be used normally. However your var
is an IQueryable
of an Anonymous type, this won't work. To be able to pass them to other functions you can either use a Tuple or have to define the class yourself and use it in the linq query.
Upvotes: 1
Reputation: 127593
Your var is a Annonmous Type, you can't pass it out of the scope of the function (Well you can with dynamic
or ExpandoObject
, but it is not recommended).
If you want to pass the result to another method you will need a concrete type to do it.
//Elsewhere in your code
class Result
{
public usercontact UserContact {get; set;}
public EmailRecipientinGroup Group {get; set;}
public Zeekuser ZeekUser {get; set;}
}
var query = (from s in dc.UserContacts
join g in dc.EmailRecipientInGroups on s.UserEmailRecipient.RID equals g.RID
join zk in dc.ZeekUsers on s.UserID equals zk.UserId
where s.aspnet_User.LoweredUserName.Equals(strUserName.ToLower())
&& !g.UserEmailRecipientGroup.IsDeleted
&& !s.UserEmailRecipient.IsDeleted
select new Result{ UserContact = s, Group = g, ZeekUser = zk }); //Only this line changed.
query
will now be a IQueryable<Result>
which you can pass around to other functions.
Upvotes: 5