使用下面的简单示例,使用Linq to SQL从多个表返回结果的最佳方法是什么?
假设我有两个表:
Dogs: Name, Age, BreedId
Breeds: BreedId, BreedName
我想返回所有的狗与他们的育种名称。我应该让所有的狗使用这样的东西,没有问题:
public IQueryable<Dog> GetDogs()
{
var db = new DogDataContext(ConnectString);
var result = from d in db.Dogs
join b in db.Breeds on d.BreedId equals b.BreedId
select d;
return result;
}
但如果我想要有品种的狗,并尝试这样做,我有问题:
public IQueryable<Dog> 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;
}
现在我意识到编译器不让我返回一组匿名类型,因为它期待狗,但有没有一种方法来返回这个而不必创建一个自定义类型?或者我必须为DogsWithBreedNames创建自己的类,并在选择中指定该类型?或者还有其他更简单的方法吗?
在c# 7中你现在可以使用元组了!这样就不需要为了返回结果而创建一个类。
下面是一个示例代码:
public List<(string Name, string BreedName)> 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
}.ToList();
return result.Select(r => (r.Name, r.BreedName)).ToList();
}
您可能需要安装System。ValueTuple nuget包。
BreedId in the Dog table is obviously a foreign key to the corresponding row in the Breed table. If you've got your database set up properly, LINQ to SQL should automatically create an association between the two tables. The resulting Dog class will have a Breed property, and the Breed class should have a Dogs collection. Setting it up this way, you can still return IEnumerable<Dog>, which is an object that includes the breed property. The only caveat is that you need to preload the breed object along with dog objects in the query so they can be accessed after the data context has been disposed, and (as another poster has suggested) execute a method on the collection that will cause the query to be performed immediately (ToArray in this case):
public IEnumerable<Dog> GetDogs()
{
using (var db = new DogDataContext(ConnectString))
{
db.LoadOptions.LoadWith<Dog>(i => i.Breed);
return db.Dogs.ToArray();
}
}
然后,访问每只狗的品种是微不足道的:
foreach (var dog in GetDogs())
{
Console.WriteLine("Dog's Name: {0}", dog.Name);
Console.WriteLine("Dog's Breed: {0}", dog.Breed.Name);
}