C# 实施";加入;在实体框架中使用各种表

C# 实施";加入;在实体框架中使用各种表,c#,sql-server,entity-framework,linq,entity-framework-core,C#,Sql Server,Entity Framework,Linq,Entity Framework Core,我有三张桌子: 材料: 身份证 头衔 内容 喜欢: 身份证 实现 用户ID 孤岛 访客: 身份证 用户ID 实现 日期 阅读现在 我想得到一个像这样的对象: 头衔 内容 伯爵喜欢 计数访客 我试着做到以下几点: from mat in ctx.materials let visitors = mat.VisitorsCollection.Where(x=>x.ReadNow).Count() let likes = mat.LikesCollection.Where(x=>x.IsL

我有三张桌子:

材料

  • 身份证
  • 头衔
  • 内容
  • 喜欢

  • 身份证
  • 实现
  • 用户ID
  • 孤岛
  • 访客

  • 身份证
  • 用户ID
  • 实现
  • 日期
  • 阅读现在
  • 我想得到一个像这样的对象:

  • 头衔
  • 内容
  • 伯爵喜欢
  • 计数访客
  • 我试着做到以下几点:

    from mat in ctx.materials
    let visitors = mat.VisitorsCollection.Where(x=>x.ReadNow).Count()
    let likes = mat.LikesCollection.Where(x=>x.IsLiked).Count()
    let iliked = mat.LikesCollection.Where(x=>x.UserID == myID && x.IsLiked).Any()
    select new {
       Material = mat,
       Visitors = visitors,
       Likes = likes,
       Liked = iliked
    }
    
    from mat in ctx.materials
    join lik in ctx.Likes.Where(x=>x.UserID == myID && x.IsLiked) on map.ID equals lik.MaterialID 
    select new {
       Material = mat,
       Liked = lik.Any()
    }
    
    我选择了一些材料,实体框架分别接收访客数量等数据

    我还尝试了以下方法:

    from mat in ctx.materials
    let visitors = mat.VisitorsCollection.Where(x=>x.ReadNow).Count()
    let likes = mat.LikesCollection.Where(x=>x.IsLiked).Count()
    let iliked = mat.LikesCollection.Where(x=>x.UserID == myID && x.IsLiked).Any()
    select new {
       Material = mat,
       Visitors = visitors,
       Likes = likes,
       Liked = iliked
    }
    
    from mat in ctx.materials
    join lik in ctx.Likes.Where(x=>x.UserID == myID && x.IsLiked) on map.ID equals lik.MaterialID 
    select new {
       Material = mat,
       Liked = lik.Any()
    }
    
    但现在出现了一个错误:

    Microsoft.EntityFrameworkCore.Query:警告:无法翻译LINQ表达式“Any()”,将在本地对其求值


    如果数据库中有外键,那么EF将在对象之间生成链接,因此您需要做的就是:

    var result = ctx.materials.Select(x => 
         new SomeClass{
              Material = x,
              Visitors = x.Visitors.Where(v => v.ReadNow).Count(),
              Likes = x.Likes.Where(y => y.IsLiked).Count(),
              Liked = x.Likes.Where(z => z.IsLiked && z.UserID == myID).Count()
         }).ToList();
    

    语法可能不完全正确,但你明白了…

    如果数据库中有外键,EF将在对象之间生成链接,因此你需要做的就是:

    var result = ctx.materials.Select(x => 
         new SomeClass{
              Material = x,
              Visitors = x.Visitors.Where(v => v.ReadNow).Count(),
              Likes = x.Likes.Where(y => y.IsLiked).Count(),
              Liked = x.Likes.Where(z => z.IsLiked && z.UserID == myID).Count()
         }).ToList();
    

    语法可能不是完全正确的,但是你得到了点…

    如果你使用的是实体框架,考虑使用这些连接,而不是自己执行连接。 您有一系列
    材料
    ,其中每个
    材料
    都有零个或多个
    和零个或多个
    访问者
    ,两者都是一对多关系,使用外键将
    材料

    如果您遵循了,您将拥有类似于以下内容的类

    class Material
    {
         public int Id {get; set;}
         public string Title {get; set;}
         public string Content {get; set;}
    
         // every Material has zero or more Likes (one-to-many)
         public virtual ICollection<Like> Likes {get; set;}
    
         // every Material has zero or more Visitors (one-to-many)
         public virtual ICollection<Visitor> Visitors {get; set;}
    }
    
    这就是实体框架检测一对多关系所需的全部内容。这可能是因为您需要不同的表名或列的不同标识符。在这种情况下,需要属性或fluent API

    在实体框架中,表的列由非虚拟属性表示。虚拟属性表示表之间的关系(一对多、多对多等)

    正确获得类定义后,您的查询将变得简单且非常直观:

    要求:

    从我收集的资料中,给我每一份资料的标题、内容、喜欢的数量和访客数量:

    换句话说:从我的全部资料中,只保留那些。。。从每个剩余材质创建一个新对象:

    • 标题是材料的标题
    • 内容就是材料的内容
    • LikeCount是此材质的类数(具有真实IsLiked)
    • NrOfVisitors是此材料的访问者数量(即…)

    实体框架知道你的关系,知道需要一个组连接。

    如果你使用实体框架,考虑使用这些连接,而不是自己执行连接。 您有一系列

    材料
    ,其中每个
    材料
    都有零个或多个
    和零个或多个
    访问者
    ,两者都是一对多关系,使用外键将
    材料

    如果您遵循了,您将拥有类似于以下内容的类

    class Material
    {
         public int Id {get; set;}
         public string Title {get; set;}
         public string Content {get; set;}
    
         // every Material has zero or more Likes (one-to-many)
         public virtual ICollection<Like> Likes {get; set;}
    
         // every Material has zero or more Visitors (one-to-many)
         public virtual ICollection<Visitor> Visitors {get; set;}
    }
    
    这就是实体框架检测一对多关系所需的全部内容。这可能是因为您需要不同的表名或列的不同标识符。在这种情况下,需要属性或fluent API

    在实体框架中,表的列由非虚拟属性表示。虚拟属性表示表之间的关系(一对多、多对多等)

    正确获得类定义后,您的查询将变得简单且非常直观:

    要求:

    从我收集的资料中,给我每一份资料的标题、内容、喜欢的数量和访客数量:

    换句话说:从我的全部资料中,只保留那些。。。从每个剩余材质创建一个新对象:

    • 标题是材料的标题
    • 内容就是材料的内容
    • LikeCount是此材质的类数(具有真实IsLiked)
    • NrOfVisitors是此材料的访问者数量(即…)

    实体框架知道您的关系,并且知道需要GroupJoin。

    如果
    ctx.Likes.Any(x=>x.UserID==myID&&x.IsLiked)
    有效,请尝试。@PeterB谢谢您的回答!不幸的是,如果我像collection.Any(…)那样做,那么什么都不会改变,我会收到许多个人请求。问题是什么?第一个查询查找EF预期/推荐的连接方式。客户评估/N+1查询?请更新帖子。还要指定确切的EF核心版本,因为它确实很重要。@IvanStoev谢谢你的回答。我回答了《先驱报》的回答。拜托,我在那里写了问题所在。问题是我有上面提到的额外数据。结果,我收到了100个请求,而不是一个请求。如果
    ctx.Likes.Any(x=>x.UserID==myID&&x.IsLiked)
    有效,请尝试一下。@PeterB谢谢你的回答!不幸的是,如果我像collection.Any(…)那样做,那么什么都不会改变,我会收到许多个人请求。问题是什么?第一个查询查找EF预期/推荐的连接方式。客户评估/N+1查询?请更新帖子。还要指定确切的EF核心版本,因为它确实很重要。@IvanStoev谢谢你的回答。我回答了《先驱报》的回答。拜托,我在那里写了问题所在。问题是我有上面提到的额外数据。结果,我收到了100个请求,而不是一个。谢谢你的回答!这个查询还为数据库中的每一行返回许多额外的查询