如何使用查询LINQ三个表并返回所有数据?

时间:2015-11-22 03:17:55

标签: c# entity-framework linq

我在看this,但我的问题有点不同。我正在构建一个简化的搜索引擎,允许用户根据标签查找汽车。我正在使用返回JSON数据的WebApi,但我只能弄清楚如何返回我想要的一些数据。在搜索引擎中,我想要包括所有过滤车辆的列表以及所有相关标签。 当前代码仅返回汽车而不返回标签。希望得到一些帮助。

通缉输出:

Audi
fast, groovy, slick

BMW
fast, classic

...

我有来自SQL Server和C#强类型类(实体框架)的以下表格,如下所示:

//    Cars { Id, Name }
//    Tags { Id, Title }
//    CarTags { TagId, CarId }

Cars[] Cars = new Cars[]
{
    new Cars(1, "Audi"),
    new Cars(2, "BMW"),
    new Cars(3, "Chrysler"),
    new Cars(4, "Ford"),
};

Tags[] Tags = new Tags[]
{
    new Tags(1, "fast"),
    new Tags(2, "groovy"),
    new Tags(3, "slick"),
    new Tags(4, "classic"),
};

CarTags[] CarTags = new CarTags[]
{
    new CarTags(1,1),
    new CarTags(2,1),
    new CarTags(3,1),
    new CarTags(1,2),
    new CarTags(4,2)
};

SQL查询可能如下所示:

SELECT * FROM Cars c
INNER JOIN
    CarTags ct on c.Id = ct.CarId
INNER JOIN 
    Tags t on ct.TagId = t.Id
WHERE 
    t.Title = 'fast'

...当然会返回与标签相关的所有汽车"快速"。

对于LINQ我正在做这样的事情:

var q = from c in Cars
        join ct in CarTags on c.Id equals ct.CarId
        join t in Tags on ct.TagId equals t.Id
        where t.Title == "fast"
        select c;

// return data from WebApi 
var page = curPage; // curPage fetched via parameter
var take = 6;
var skip = (page - 1) * take;
return new PagedList<Cars>
{
    Filtered = q.Count(),
    Model = q.Skip(skip).Take(take).ToList()
};

PagedList是这样的:

public class PagedList<T>
{
    public int Filtered { get; set; }
    public IEnumerable<T> Model { get; set; }
}

当我在接收端循环这些数据时,我使用类似的东西,但我只能枚举汽车而不是标签。

foreach (var item in q) // item = car object
{
    Console.WriteLine("\n\n" + car.Name);
    //foreach (var tag in item) // can't enumerate all associated tags here
    //{
    //    Console.Write(tag.Title + ", ");
    //}
}

我被困在Linq。如何在Linq中完成此类功能?

2 个答案:

答案 0 :(得分:1)

您告诉linq的select c行仅返回cars类。要获得所有这些,您可以创建一个新对象,例如CarsAndTags,其中包含两者的属性。然后你会将你的select语句更新为这样。

select new CarsAndTags{Name= c.name,tag=ct.tag}

答案 1 :(得分:0)

在CarTag类中,您可以创建两个新属性。一个用于汽车,一个用于标签。这些将是其他表的外键,并且是该对象的外键。例如,您的类看起来像这样。

public class CarTag
{
    public int CarId {get;set;}
    public int TagId {get;set;}

    [ForeignKey("CarId")]
    public virtual Car Cars {get;set;}

    [ForeignKey("TagId")]
    public virtual Tag Tags {get;set;}
}

然后你的查询会是这样的。

var q = from c in Cars
    join ct in CarTags on c.Id equals ct.CarId
    join t in Tags on ct.TagId equals t.Id
    where t.Title == "fast"
    select ct;

这会延迟加载Car和Tag,因为它们有外来引用。