首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用LINQ到实体生成信息

使用LINQ到实体生成信息
EN

Stack Overflow用户
提问于 2010-05-20 19:39:09
回答 3查看 146关注 0票数 1

我是在一个网站上的用户可以添加标签到他们张贴的书籍,很像目前做的问题堆栈溢出。

代码语言:javascript
运行
复制
Books
{
bookId,
Title
}

Tags
{
Id
Tag
}

BooksTags
 {
 Id
 BookId
 TagId
 }

这是很少的样本记录。

代码语言:javascript
运行
复制
Books
BookId Title
113421  A
113422  B

Tags
Id Tag
1  ASP 
2  C#
3  CSS
4  VB
5  VB.NET
6  PHP
7  java
8  pascal

 BooksTags   
 Id  BookId  TagId
 1  113421    1
 2  113421    2
 3  113421    3
 4  113421    4
 5  113422    1
 6  113422    4
 7  113422    8

问题

  1. 我需要用LINQ查询来编写一些东西,这些查询根据标记提供数据: 查询bookIds where tagid = 1 返回bookid: 113421, 113422 查询2tags 1 and 2 返回113421
  2. 我需要标签和他们的计数,以显示在相关标签,所以在第一种情况下,我的相关标签类应该有以下结果。 RelatedTags标签计数2 1 3 1 4 2 8 1

第二例

代码语言:javascript
运行
复制
RelatedTags
Tag Count
3   1
4   1

在LINQ里我该怎么做?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-05-20 20:20:04

在第一部分中,有趣的限制是,书中必须匹配输入的每个标记,因此"where tagid == someId“的where子句将无法真正工作。我设想像这样的东西(示例)

代码语言:javascript
运行
复制
List<int> selectedTagIds = new List<int>() { 1, 2 };
var query = from book in books
            join booktag in booktags 
            on book.Id equals booktag.BookId 
            join selectedId in selectedTagIds 
            on booktag.TagId equals selectedId 
            group book by book into bookgroup 
            where bookgroup.Count() == selectedTagIds.Count
            select bookgroup.Key;

它基本上执行一个连接,从图书到书签,也到选择的标签ids列表,并将选择限制在与book->标记匹配的计数等于所选标记ids的计数的位置。

拉出相关的标签,也许是这样的

代码语言:javascript
运行
复制
var relatedTags = from book in query // use original query as base
                    join booktag in booktags
                    on book.Id equals booktag.BookId
                    join tag in tags
                    on booktag.TagId equals tag.Id
                    where !selectedTagIds.Contains(tag.Id) // exclude selected tags from related tags
                    group tag by tag into taggroup
                    select new
                    {
                        Tag = taggroup.Key,
                        Count = taggroup.Count()
                    };

快速示例的完整代码。不完全是这样,但你知道这个主意。

代码语言:javascript
运行
复制
using System;
using System.Collections.Generic;
using System.Linq;

namespace StackOverflow
{
    class Program
    {
        static void Main()
        {
            List<Book> books = new List<Book>() 
            {
                new Book() { Id = 113421, Title = "A" },
                new Book() { Id = 113422, Title = "B" }
            };

            List<Tag> tags = new List<Tag>()
            {
                new Tag() { Id = 1, Name = "ASP" },
                new Tag() { Id = 2, Name = "C#" },
                new Tag() { Id = 3, Name = "CSS" },
                new Tag() { Id = 4, Name = "VB" },
                new Tag() { Id = 5, Name = "VB.NET" },
                new Tag() { Id = 6, Name = "PHP" },
                new Tag() { Id = 7, Name = "Java" },
                new Tag() { Id = 8, Name = "Pascal" }
            };

            List<BookTag> booktags = new List<BookTag>()
            {
                new BookTag() { Id = 1, BookId = 113421, TagId = 1 },
                new BookTag() { Id = 2, BookId = 113421, TagId = 2 },
                new BookTag() { Id = 3, BookId = 113421, TagId = 3 },
                new BookTag() { Id = 4, BookId = 113421, TagId = 4 },
                new BookTag() { Id = 5, BookId = 113422, TagId = 1 },
                new BookTag() { Id = 6, BookId = 113422, TagId = 4 },
                new BookTag() { Id = 7, BookId = 113422, TagId = 8 }
            };


            List<int> selectedTagIds = new List<int>() { 1,2 };

            // get applicable books based on selected tags

            var query = from book in books
                        join booktag in booktags
                        on book.Id equals booktag.BookId
                        join selectedId in selectedTagIds
                        on booktag.TagId equals selectedId
                        group book by book into bookgroup
                        where bookgroup.Count() == selectedTagIds.Count
                        select bookgroup.Key;

            foreach (Book book in query)
            {
                Console.WriteLine("{0}\t{1}",
                    book.Id,
                    book.Title);
            }

            // get related tags for selected tags

            var relatedTags = from book in query // use original query as base
                              join booktag in booktags
                              on book.Id equals booktag.BookId
                              join tag in tags
                              on booktag.TagId equals tag.Id
                              where !selectedTagIds.Contains(tag.Id) // exclude selected tags from related tags
                              group tag by tag into taggroup
                              select new
                              {
                                  Tag = taggroup.Key,
                                  Count = taggroup.Count()
                              };

            foreach (var relatedTag in relatedTags)
            {
                Console.WriteLine("{0}\t{1}\t{2}",
                    relatedTag.Tag.Id,
                    relatedTag.Tag.Name,
                    relatedTag.Count);
            }

            Console.Read();
        }
    }

    class Book
    {
        public int Id { get; set; }
        public string Title { get; set; }
    }

    class Tag
    {
        public int Id { get; set; }
        public string Name { get; set; }
    }

    class BookTag
    {
        public int Id { get; set; }
        public int BookId { get; set; }
        public int TagId { get; set; }
    } 
}

因此,对于选定的标签1和2,您将得到图书A,相关的标签将是3 (CSS)和4 (VB)。

票数 0
EN

Stack Overflow用户

发布于 2010-05-20 20:00:57

只需执行外键映射1:N或1:1关系中的表,然后让设计人员为您创建导航属性。(书籍:BooksTags将1:N从Books.BookID映射到BooksTags.BookID,BooksTags.TagID映射1:1到Tags.TagID)。这实际上是一个变相的N:M关系。我不知道设计人员是否直接发现了这一点,但是通过一些修改,您可以获得正确的导航属性。

现在请回答以下问题:

  1. model.Tags.Where(t => t.ID == 1).Books.Select(b => b.ID)
  2. 获取书中的所有标记,并在BooksTags上加入该表,这样您就可以简单地使用Count()来获取计数。
票数 0
EN

Stack Overflow用户

发布于 2010-05-21 03:47:08

这与答案本身没有直接关系,但是您可能想看看衬垫,因为它将帮助您直接从数据库构建L2S语句。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2877202

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档