那么你的数据库有一个表填充 Posts
. 每 Post
似乎是发布的零或更多(或许一个或多个)的用户。 在我看来,你也有一个表 Users
. 每 User
已经发布的零或更多 Posts
.
在我看来,有许多对多关系 Users
和 Posts
:每个用户都已经张贴为零或更多员额;每一个职位已经公布的零(一个吗?) 或更多的用户。
通常在一个数据库将实施一个"多对多"的关系有一个特别表:结表。
你不使用结表。 你的数据库是不正常化。
也许你目前的问题是可以解决没有改变的数据库,但是我看到这么多的问题你必须要解决,也许现在不行,但在不久的将来:什么巨大的工作需要做,如果你想要删除的用户? 如何做你得到所有"员额,用户[10]发布了"那么,如果用户[10]不想提到了在出版物清单后[23]? 如何防止用户[10]提到的两次后[23]:
UserIds = 10, 3, 5, 10, 7, 10
正常的数据库
考虑到更新的数据库联接表和摆脱了串列 Post.UserIds
. 这样就解决了所有这些问题。
class User
{
public int Id {get; set;}
public string Name {get; set;}
...
// every user has posted zero or more Posts:
public virtual ICollection<Post> Posts {get; set;}
}
class Post
{
public int Id {get; set;}
public string Title {get; set;}
public Datetime PublicationDate {get; set;}
...
// every Post has been posted by zero or more Users:
public virtual ICollection<User> Users {get; set;}
}
结表:
public UsersPost
{
public int UserId {get; set;}
public int PostId {get; set;}
}
注:[UserId,帐子id]是独一无二的。 使用这一主键
在实体框架的列表代表非虚拟的性质。 虚拟性质反映的关系表之间(的一对-很多,很多-对-很多)
注:外国关键的是一个真正的列表,因此一外国的关键是非虚拟的。
要配置多对多,可以使用流利API:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// User - Post: many-to-many
modelBuilder.Entity<User>()
.HasMany<Post>(user => user.Posts)
.WithMany(post => post.Users)
.Map(userpost =>
{
userpost.MapLeftKey(nameof(UserPost.UserId));
userpost.MapRightKey(nameof(UserPost.PostId));
userpost.ToTable(nameof(UserPost));
});
// primary key of UserPost is a composite key:
modelBuilder.Entity<UserPost>()
.HasKey(userpost => new {userpost.UserId, userpost.PostId});
}
回到你的问题
一旦你已经实现的结表数据请求将是容易的:
int userId = ...
// get this User with all his Posts:
var userWithPosts= dbContext.Users
.Where(user => user.Id == userId)
.Select(user => new
{
// Select only the user properties that you plan to use
Name = user.Name,
...
Posts = user.Posts.Select(post => new
{
// Select only the Post properties that you plan to use
Id = post.Id
PublicationDate = post.PublicationDate,
...
})
.ToList(),
});
或者,如果你不想要任何用户的数据,开始与员额:
var postsOfUser = dbContext.Posts
.Where(post => post.Users.Any(user => user.Id == userId))
.Select(post => new {...});
有些人不喜欢使用虚拟ICollections,或者他们使用一个版本的实体的框架,该框架不支持这一点。 在这种情况下,只有做到的加入自己:
int userId = ...
var postsOfThisUser = dbContext.UserPosts
// keep only the UserPosts of this user:
.Where(userPost => post.UserId == userId)
// join the remaining UserPosts with Posts
.Join(dbContext.Posts,
userpost => userpost.PostId, // from every UserPost get the foreign key to Post
post => post.Id, // from every Post, get the primary key
// parameter resultSelector: from every UserPost with matching Post make one new
(userPost, post) => new
{
Title = post.Title,
PublicationDate = post.PublicationDate,
...
}
}
解决方案没有规范化的数据库
如果你真的不能说服你的项目领导人,一个适当的数据库,将防止一个很大的问题,在未来,考虑到创建一个SQL的文本,获得适当的员额。
你的代码的第代表当前的执行情况的数据库。 它描述表和之间的关系表。 加入一个方法来获取职位的用户,似乎我一个合法的方法代码的第.
我SQL是有点生疏,你就会知道更好的方式比我如何做到这一SQL。 我猜你会得到的要点:
public IEnumerable<Post> GetPostsOfUser(int userId)
{
const string sqlText = "Select Id, ... from Posts where ..."
object[] parameters = new object[] {userId};
return this.Database.SqlQuery(sqlText, parameters);
}