如何使两个联接生成一个选择?

时间:2011-02-02 22:27:17

标签: c# linq entity-framework

我目前有3张桌子:

News
ID | Title

Tag
ID | Name

TaggedContent
ContentID | TagID

我有两个上下文对象:NewsEntitiesTagsEntities

我想在我的应用程序中选择新闻使用的所有标签:

static void Main(string[] args)
{
    IEnumerable<dynamic> something = null;

    IEnumerable<News.Data.News> news = null;
    IEnumerable<Tags.Data.Tag> tags = null;
    IEnumerable<TaggedContent> tagged = null;

    using (var db = new NewsEntities())
    {
        news = db.News.ToList(); // 1 select
    }

    using (var db = new TagsEntities())
    {
        something = news.Join(db.TaggedContents.ToList(),
            n => n.ID,
            tc => tc.ContentID,
            (n, tc) => new { tc.TagID }); // 1 select

        something = something.Join(db.Tags.ToList(),
            tid => tid.TagID,
            t => t.ID,
            (tid, t) => t); // 1 select
    }

    var result = something;
}

我目前正在生成 3个选项。如何将其减少到2?或者如果可能的话我想在不合并实体的情况下减少到1。

2 个答案:

答案 0 :(得分:2)

由于您正在加入来自不同情境的实体,因此您只能少于2次选择。

您的加入是一个简单的身份检查,因此您可以这样做:

var ids = db.News.Select(x => x.ID).ToList();

您现在拥有新闻表中所有ID的本地副本 - 第一个选择。然后将你的第一个“东西”改为:

something = db.TaggedContents
    .Where(x => ids.Contains(x.ContentID))
    .Select(x => new { x.TagID });

由于延迟执行,第二个语句本身不会生成选择。您现在可以删除第三个语句中的ToList()

something = something.Join(db.Tags,
    tid => tid.TagID,
    t => t.ID,
    (tid, t) => t);

当你最终枚举something时,你将有第二次选择。

答案 1 :(得分:0)

使用在创建DataContext时传递的DataLoadOptions类。

       DataLoadOptions options = new DataLoadOptions();
       db.LoadOptions = options;
       options.LoadWith((News n) => n.Tags);

对剩余的数据进行加入。