我有以下实体:
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; }
}
一个用户可以拥有多个帖子,一个帖子可以有多个个帖子。 问题是反应应该存储对其帖子的引用和响应的用户。我可以在用户和帖子之间建立一对多的关系。
如何使用Entity Framework映射此关系?
答案 0 :(得分:3)
在最后评论后添加
如果您按照the entity framework code-first conventions获得一对多关系,则不必添加任何属性,也不必使用流畅的API来告诉实体框架您想要什么。
只有当您需要不同的表名,属性类型,列名或其他关于表之间关系的专业时,您才需要属性或流畅的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;}
...
}
对这篇文章的反应:
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;}
}
实际上,实际上只需要了解您希望一对多关系并找出哪些属性应该成为外键的实体框架。实体框架也理解你没有帖子就没有反应。如果您尝试删除帖子,其所有反应都将被删除。
我更改了一些项目,使其更符合代码优先修复。
Post
,多个Posts
ICollections的一个优点是,如果你想要一个User-with-his-Posts,你不需要在外键上使用相当困难的左外连接。
要让所有老用户拥有他们的全部或部分帖子,您可以使用ICollection。实体框架将在适当的左外连接中为您翻译:
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,
}),
}),
});