使用下面的简单示例,使用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创建自己的类,并在选择中指定该类型?或者还有其他更简单的方法吗?


当前回答

你可以这样做:


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();
}

其他回答

这并没有完全回答你的问题,但谷歌根据关键字引导我到这里。这是从列表中查询匿名类型的方法:

var anon = model.MyType.Select(x => new { x.Item1, x.Item2});

如果你在你的数据库中有一个关系设置,在BreedId上有一个外键约束,你还没有得到吗?

所以我现在可以调用:

internal Album GetAlbum(int albumId)
{
    return Albums.SingleOrDefault(a => a.AlbumID == albumId);
}

在调用它的代码中:

var album = GetAlbum(1);

foreach (Photo photo in album.Photos)
{
    [...]
}

在你的实例中,你会调用像dog。breed。breedname这样的东西-正如我说的,这依赖于你的数据库是用这些关系建立的。

正如其他人所提到的,如果存在数据库调用问题,DataLoadOptions将有助于减少数据库调用。

如果你要归还《Dogs》,你应该这样做:

public IQueryable<Dog> GetDogsWithBreedNames()
{
    var db = new DogDataContext(ConnectString);
    return from d in db.Dogs
           join b in db.Breeds on d.BreedId equals b.BreedId
           select d;
}

如果您希望Breed立即加载而不是延迟加载,只需使用适当的DataLoadOptions构造。

尝试这样获取动态数据。您可以转换List<>的代码

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.FirstOrDefault();
}

dynamic dogInfo=GetDogsWithBreedNames();
var name = dogInfo.GetType().GetProperty("Name").GetValue(dogInfo, null);
var breedName = dogInfo.GetType().GetProperty("BreedName").GetValue(dogInfo, null);

只需要选择狗,然后使用dog.Breed。BreedName,这应该可以正常工作。

如果你有很多狗,使用DataLoadOptions。LoadWith来减少db调用的数量。