Using the simple example below, what is the best way to return results from multiple tables using Linq to SQL?
Say I have two tables:
Dogs: Name, A
You could do something like this:
public System.Collections.IEnumerable GetDogsWithBreedNames()
{
var db = new DogDataContext(ConnectString);
var result = from d in db.Dogs
join b in db.Breeds on d.BreedId equals b.BreedId
select new
{
Name = d.Name,
BreedName = b.BreedName
};
return result.ToList();
}
If the main idea is to make the SQL select statement sent to the Database server have only the required fields, and not all the Entity fields, then u can do this:
public class Class1
{
public IList<Car> getCarsByProjectionOnSmallNumberOfProperties()
{
try
{
//Get the SQL Context:
CompanyPossessionsDAL.POCOContext.CompanyPossessionsContext dbContext
= new CompanyPossessionsDAL.POCOContext.CompanyPossessionsContext();
//Specify the Context of your main entity e.g. Car:
var oDBQuery = dbContext.Set<Car>();
//Project on some of its fields, so the created select statment that is
// sent to the database server, will have only the required fields By making a new anonymouse type
var queryProjectedOnSmallSetOfProperties
= from x in oDBQuery
select new
{
x.carNo,
x.eName,
x.aName
};
//Convert the anonymouse type back to the main entity e.g. Car
var queryConvertAnonymousToOriginal
= from x in queryProjectedOnSmallSetOfProperties
select new Car
{
carNo = x.carNo,
eName = x.eName,
aName = x.aName
};
//return the IList<Car> that is wanted
var lst = queryConvertAnonymousToOriginal.ToList();
return lst;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
throw;
}
}
}
This doesn't exactly answer your question, but Google led me here based on the keywords. This is how you might query an anonymous type from a list:
var anon = model.MyType.Select(x => new { x.Item1, x.Item2});
I tend to go for this pattern:
public class DogWithBreed
{
public Dog Dog { get; set; }
public string BreedName { get; set; }
}
public IQueryable<DogWithBreed> GetDogsWithBreedNames()
{
var db = new DogDataContext(ConnectString);
var result = from d in db.Dogs
join b in db.Breeds on d.BreedId equals b.BreedId
select new DogWithBreed()
{
Dog = d,
BreedName = b.BreedName
};
return result;
}
It means you have an extra class, but it's quick and easy to code, easily extensible, reusable and type-safe.
Now I realize that the compiler won't let me return a set of anonymous types since it's expecting Dogs, but is there a way to return this without having to create a custom type?
Use use object to return a list of Anonymous types without creating a custom type. This will work without the compiler error (in .net 4.0). I returned the list to the client and then parsed it on JavaScript:
public object GetDogsWithBreedNames()
{
var db = new DogDataContext(ConnectString);
var result = from d in db.Dogs
join b in db.Breeds on d.BreedId equals b.BreedId
select new
{
Name = d.Name,
BreedName = b.BreedName
};
return result;
}
If you have a relationship setup in your database with a foriegn key restraint on BreedId don't you get that already?
So I can now call:
internal Album GetAlbum(int albumId)
{
return Albums.SingleOrDefault(a => a.AlbumID == albumId);
}
And in the code that calls that:
var album = GetAlbum(1);
foreach (Photo photo in album.Photos)
{
[...]
}
So in your instance you'd be calling something like dog.Breed.BreedName - as I said, this relies on your database being set up with these relationships.
As others have mentioned, the DataLoadOptions will help reduce the database calls if that's an issue.