【问题标题】:LINQ count in same table同一张表中的 LINQ 计数
【发布时间】:2023-03-12 04:56:01
【问题描述】:

我的代码优先实体框架上下文中有这个类,如下所示-

class User
{
   int UserId;
   string Name;;
   int ParentId;
}

数据库表:

  UserId    Name  ParentId
   1         abc     0
   3         pqr     1
   4         xyz     1

我想从上面的数据中选择 -

 UserId     Name   ChildQuantity
   1         abc        2
   3         pqr        0
   4         xyz        0

我可以使用 LINQ 或 Lambda 吗?

【问题讨论】:

    标签: entity-framework linq code-first


    【解决方案1】:

    您可以将表加入到自身中(您需要在此处加入组):

    from u in db.Users
    join c in db.Users on u.UserId equals c.ParentId into children
    select new
    {
        u.UserId,
        u.Name,
        ChildQuantity = children.Count()
    };
    

    或者您可以为用户类中的子集合设置导航属性。使用此导航属性查询将如下所示:

       from u in db.Users
       select new {
          u.UserId,
          u.Name,
          ChildQuantity = u.Children.Count()
       };
    

    我相信它更干净一点。您需要做的就是为孩子添加关联属性:

    public class User
    {
        public int UserId { get; set; }
        public string Name { get; set; }        
        public int? ParentId { get; set; } // Note: this property is not required
        public IList<User> Children { get; set; }
    }
    

    并提供映射:

    modelBuilder.Entity<User>().HasMany(u => u.Children)
        .WithOptional().HasForeignKey(u => u.ParentId).WillCascadeOnDelete(false);
    

    生成的查询将如下所示:

    SELECT
        [Extent1].[UserId] AS [UserId],
        [Extent1].[Name] AS [Name],
        (SELECT
            COUNT(1) AS [A1]
            FROM [dbo].[Users] AS [Extent2]
            WHERE [Extent1].[UserId] = [Extent2].[ParentId]) AS [C1]
        FROM [dbo].[Users] AS [Extent1]
    

    【讨论】:

    • @Servey,我尝试了导航属性的方法。但它给出了异常-“EntityFramework.dll 中发生了 System.Data.Entity.ModelConfiguration.ModelValidationException”。有什么帮助吗?
    • @s.k.paul 选项和join 可以正常工作吗?
    • 加入工作正常。我刚刚尝试了您建议的另一个选项“关联属性”。这是错误详细信息-“ UserDetail_Children_Source_UserDetail_Children_Target: : 引用约束的从属角色中所有属性的类型必须与主体角色中的相应属性类型相同。实体'UserDetail'上的属性'ParentId'的类型确实与引用约束“UserDetail_Children”中实体“UserDetail”上的属性“UserId”类型不匹配。”
    • @s.k.paul 您是否使用了与答案中完全相同的设置 - int? 用于父 ID,WillCascadeOnDelete(false)
    • UserId 很长。但是我错误地将 ParentId 声明为 int。改正后,现在一切正常。
    【解决方案2】:

    这样的?

    var ans = from p in src select new { p.UserID, p.Name, ChildQuantity = src.Where(c => c.ParentId == p.UserID).Count() };
    

    【讨论】:

    • 听起来不错。它真的会起作用吗?让我检查一下。无论如何,谢谢你的想法。
    • 它的工作。但谢尔盖别列佐夫斯基的回答更具描述性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-18
    • 1970-01-01
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多