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


当前回答

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

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

其他回答

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

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

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

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

我倾向于这样的模式:

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

这意味着你有一个额外的类,但它是快速和容易编码,易于扩展,可重用和类型安全。

只是补充一下我的意见:-) 我最近学习了一种处理匿名对象的方法。它只能在针对。net 4框架时使用,并且只能在添加对System.Web.dll的引用时使用,但它非常简单:

...
using System.Web.Routing;
...

class Program
{
    static void Main(string[] args)
    {

        object anonymous = CallMethodThatReturnsObjectOfAnonymousType();
        //WHAT DO I DO WITH THIS?
        //I know! I'll use a RouteValueDictionary from System.Web.dll
        RouteValueDictionary rvd = new RouteValueDictionary(anonymous);
        Console.WriteLine("Hello, my name is {0} and I am a {1}", rvd["Name"], rvd["Occupation"]);
    }

    private static object CallMethodThatReturnsObjectOfAnonymousType()
    {
        return new { Id = 1, Name = "Peter Perhac", Occupation = "Software Developer" };
    }
}

为了能够添加对System.Web.dll的引用,你必须遵循rushonerok的建议:确保你的[项目的]目标框架是“。NET Framework 4“不是”。NET Framework 4客户端配置文件”。

你可以这样做:


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