I am just getting my feet wet with LINQ to SQL, and need some advice in implementing a simple scenario:
I have a method ListTagCounts that is doing an aggregate query with LINQ To SQL. I was not sure of the return type to use, so used the ToList() method and created a class just for the return type in order to get it to compile.
Schema:
Link LinkTag Tag
---------- ---------- ----------
LinkID LinkID TagID
URL TagID Name
IsDeleted
Code:
static void Main(string[] args)
{
var counts = ListTagCounts();
foreach(var c in counts)
Console.WriteLine("Tag: {0}, Count: {1}", c.Tag, c.Count);
Console.ReadKey();
}
public static List<MyReturnClass> ListTagCounts()
{
List<MyReturnClass> counts;
using (var db = new MyDbDataContext())
{
counts = (from t in db.Tags
join lt in db.LinkTags on t.TagID equals lt.TagID
join l in db.Links on lt.LinkID equals l.LinkID
where l.IsDeleted == false
select new MyReturnClass() { Tag = t.Name, Count = t.LinkTags.Count() }
).Distinct().OrderBy(t => t.Tag).ToList();
}
return counts;
}
public class MyReturnClass
{
public string Tag { get; set; }
public int Count { get; set; }
}
If I do
select new { Tag = t.Name, Count = t.LinkTags.Count() }
rather than
select new MyReturnClass() { Tag = t.Name, Count = t.LinkTags.Count() }
in my LINQ query, what should the return type be?
When you use the following syntax:
You are creating an anonymous type. The compiler generates the name of this type for you at compile-time, so there is no way for you to know what it is.
When you call ToList on the query that selects instances of this anonymous type, it’s possible that you can return the list because List implements some non-generic classes (which obviously don’t rely on the type parameter T, which you aren’t aware of) you can cast to.
Generally though, you should not let anonymous types escape the method that they are used in. If you have the need to pass the information outside of the method that the query is in, then what you are doing is correct, in creating a specialized class and then returning a sequence of that.
Note there are some justified uses for passing anonymous types outside of your method (through a return type of object, or other base classes for sequences of these types), but for cases like this, it isn’t one of them.