그래서 데이터베이스 테이블로 가득 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,PostId]가 유일하다. 사용은 기본 열쇠
Entity framework 에서는 열의 테이블에 의해 표현된 비상 속성입니다. 가상 속성을 반영하 사이의 관계 테이블(one-to-many,many-to-many)
참고:외국인이 실제 테이블에 열고,따라서 외국인 핵심 비상.
을 구성하는 다 사용할 수 있습니다,유창한 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 텍스트는 적절한 게시물에 대한 당신.
귀하의 DbContext 나타내는 현재 구현의 데이터베이스입니다. 그것을 설명하는 테이블과 테이블 사이의 관계 테이블이 있습니다. 를 추가하는 방법을 가져오는 게시물의 사용자가 날 것으로 보인다 합법적 방법에 대한 DbContext.
나의 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);
}