c# - EF - 另一个一对多内的一对多关系(Facebook 帖子/ react )

标签 c# .net entity-framework ado

我有以下实体:

public class User
{
    public User()
    {
        UserName = new Name();
        UserEmail = new Email();
    }

    [Key]
    public int Gid { get; set; }
    public Name UserName { get; set; }
    public Email UserEmail { get; set; }

    public virtual ICollection<Post> Posts { get; set; }
}

public class Post
{
    public int PostId { get; set; }
    public int UserId { get; set; }
    public string Content { get; set; }
    public string ImageUri { get; set; }

    public virtual User Author { get; set; }
}

public class Reaction
{
    public int ReactionId { get; set; }
    public string Text { get; set; }
    public string IconUri { get; set; }
}

一个用户可以有许多帖子,一个帖子可以有许多 react 。 问题是一个 react 应该存储对其帖子和使用react的用户的引用。我可以在用户和帖子之间建立一对多的关系。

我如何使用 Entity Framework 映射这种关系?

最佳答案

最后评论后补充

如果你关注the entity framework code-first conventions对于一对多关系,您不必添加任何属性,也不必使用流畅的 API 来告诉 Entity Framework 您想要什么。

只有当您需要不同的表名、属性类型、列名或其他关于表之间关系的特殊性时,您才需要属性或流畅的 API。

你的问题是因为你在类定义中省略了一些一对多的定义

您的用户:

public class User
{
    public int Id { get; set; }

    // every user has zero or more Posts (one-to-many)
    public virtual ICollection<Post> Posts { get; set; }

    ...
}

帖子:

public class Post
{
    public int Id { get; set; }

    // every Post belongs to exactly one User using foreign key
    public int UserId { get; set; }
    public virtual Post Post {get; set;}

    // every Post has zero or more Reactins (one-to-many)
    public virtual IColleciton<Reaction> Reactions {get; set;}

    ...   
}

对此帖子的 react :

public class Reaction
{
    public int Id { get; set; }

    // every Reaction belongs to exactly one Post using foreign Key:
    public int PostId {get; set;}
    public virtual Post Post {get; set; }

    ...
}

最后是您的 DbContext:

public MyDbContext : DbContext
{
    public DbSet<User> Users {get; set;}
    public DbSet<Post> Posts {get; set;}
    public DbSet<Reaction> Reactions {get; set;}
}

这就是 Entity Framework 了解您想要一对多关系并找出哪些属性应成为外键所需的全部内容。 Entity Framework 也理解没有帖子就不能有反应。如果您尝试删除帖子,将首先删除其所有反应。

我更改了一些项目以使其更符合代码优先约定。

  • 适当的多元化。一个帖子,多个帖子
  • 所有 ID 都命名为 Id(尽管您的 Id 也是按照约定)。我使用它,所以对于每个类来说主键是什么总是很清楚,即使类更改名称也是如此。
  • 所有不会成为列的项目(如 ICollections)都是虚拟的
  • 根据约定,所有一对多都有一个带有属性名称的外键
  • 没有类具有实例化成员的构造函数。毕竟,如果您执行查询,成员将被实例化并立即被查询结果替换

ICollections 的优点之一是,如果您想要一个 User-with-his-Posts,则不需要相当困难的外键左外连接。

要让所有老用户看到他们的全部或部分帖子,您可以使用 ICollection。 Entity Framework 将为您将其转换为正确的 Left outer join:

var oldUsersWithManyReactions = myDbContext.Users
    .Where(user => user.BirthDay < new DateTime(2040, 1, 1))
    .Select(user => new 
    {
        // Select only the user properties you plan to use
        Id = user.Id,
        FullName = user.Name.First + User.Name.Last,

        // select the Posts of this User:
        RecentPosts = user.Posts
            .Where(post.PublicationDate > DateTime.UtcNow.AddDay(-7))
            .Select(post => new
            {
                // again select only the Properties you want to use:
                Title = post.Title,
                PublicationDate = post.PublicationDate,
                ReactionCount = post.Reactions.Count(),
            }),
        }),
    }),
});

评论后添加

如果您想要“用户及其所有反应”,请使用 SelectMany。这实际上是一个 LINQ 问题,与 Entity-Framework 无关

var usersWithAllTheirReactions = myDbContext.Users
    .Where (user => ...)
    .Select(user => new
    {
        Id = user.Id,
        Name = ...,

        AllReactions = user.Posts
            .SelectMany(post => post.Reactions)
            .Where(reaction => ...)
            .Select(reaction => new
            {
                ReactionDate = reaction.Date,
                Text = reaction.Text,
            }),
        }),
    });

关于c# - EF - 另一个一对多内的一对多关系(Facebook 帖子/ react ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49356970/

相关文章:

c# - 如何从 C#.net 客户端列出 linux 运行进程?

c# - 在哪里可以修改 Visual Studio 中详细的 C# 编译器优化设置?

C# 依赖注入(inject)框架

c# - (附加)EF 无法从 #temp 表中选择的存储过程推断返回架构

c# - 异步方法阻止 WPF 中的 UI

c# 比较 DateTime start 和 DateTime stop 与 List<DateTime>

c# - C# 中委托(delegate)语法的问题

c# - 将多个模型的一个实例映射到 EF Core 中的一个属性

c# - 如何在 asp.net mvc 中使用 {SiteName} 处理 [Authorize]

C#.NET : Showing a simple list with a 32x32 icon column and a 2 line text column