ดังนั้นฐานข้อมูลของคุณมีโต๊ะเต็มไปด้วย Posts
. ทุกๆ Post
ดูเหมือนว่าจะส่งโดยเป็นศูนย์หรือมากกว่า(บางทีหนึ่งหรือมากกว่าเดิม)ผู้ใช้. สำหรับฉันมันดูเหมือนว่าคุณยังต้องเป็นโต๊ะของ Users
. ทุกๆ User
มีโพสต์เป็นศูนย์หรือมากกว่า Posts
.
มันดูเหมือนว่ามีหลายจะมีความสัมพันธ์ระหว่าง Users
แล้ว Posts
ทุกใช้โพสต์เป็นศูนย์หรือมากกว่ากัปตัน..เสาทางนี้;ทุกโพสถูกส่งโดยศูนย์(หนึ่ง?) หรือมากกว่าผู้ใช้.
ปกติในฐานข้อมูลคุณคงเตรียมกำหนดหลายจะมีความเกี่ยวข้องกับเป็นพิเศษโต๊ะ:ซักโต๊ะ
คุณไม่ใช้ห้องซักโต๊ะ ฐานข้อมูลของคุณไม่ใช่ normalized.
บางทีของคุณปัจจุบันจะแก้ไขปัญหาได้โดยไม่เปลี่ยนแปลงฐานข้อมูลแต่ฉันเห็นมากมายปัญหาของคุณจะต้องแก้ปัญหาอาจไม่ใช่ตอนนี้แต่ในที่ใกล้กับอนาคตอะไรมากมาทำงานคุณจะต้องทำถ้าคุณต้องการจะลบผู้ใช้งาน? คุณทำยังไงทุกอย่าง"กัปตัน..เสาทางนี้นั่นของผู้ใช้[10 งโพสต์"และถ้าผู้ใช้[10]ไม่ต้องการที่จะพูดถึงอีกแล้วในบริษัทแล้รายการของโพสต์[23]? วิธีที่จะป้องกันไม่ให้มันของผู้ใช้[10]คือพูดถึงสองครั้งในโพสต์[23]:
UserIds = 10, 3, 5, 10, 7, 10
Normalize ฐานข้อมูล
พิจารณาเพื่อปรับปรุงฐานข้อมูลกันซักโต๊ะและกำจัดของข้อคอลัมน์ 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 นเป็เปลี่ยนไปราตรีสวัสดิ์นะ ใช้นี่เป็นตัวหลักของกุญแจ
อยู่ในรายการส่วนเฟรมเวิร์กในคอลัมน์ของตารางข้อมูลเรียบร้อยแล้วนี่เป็นตัวแทนโดยที่ไม่เสมือนคุณสมบัติของ. คนเสมือนคุณสมบัติของสะท้อนที่ความสัมพันธ์ระหว่างตารางข้อมูลเรียบร้อยแล้ว(หนึ่งเพื่อหลายต่อหลายไปหลาย)
ข้อควรจำ:ต่างประเทญแจสำคัญคือจริงของคอลัมน์ในโต๊ะจึต่างบ้านต่างสำคัญคือคนที่ไม่ใช่เสมือน.
ปรับแต่งหลาย-เพื่อนมากคุณสามารถใช้อย่างดีเชี่ยวชาญรูปแบบ 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,
...
}
}
แก้ปัญหาโดยไม่มี normalized ฐานข้อมูล
ถ้าคุณไม่สามารถโน้มน้าวของคุณเป็นหัวหน้าโครงการนั้นเป็นที่เหมาะสมฐานข้อมูลจะป้องกันปัญหามากมายในอนาคตพิจารณาเพื่อสร้างเป็นภาษา sql ข้อความนั่นได้อย่างเหมาะสมกัปตัน..เสาทางนี้สำหรับคุณ
ของคุณ DbContext แสดงถึงปัจจุบัน implementation ของฐานข้อมูลของคุณ. มันอธิบายว่าโต๊ะมันทำความสะอาดและความสัมพันธ์ระหว่างตารางข้อมูลเรียบร้อยแล้ว. เพิ่มวิธีการจะเรียนที่กัปตัน..เสาทางนี้ของผู้ใช้ดูเหมือนฉันถูกวิธีการสำหรับ DbContext.
ของฉันภาษา sql วนิดหน่อยรัสตี้คุณจะรู้ว่าวิธีที่ดีกว่าที่ฉันยังต้องทำอย่างนี้อยู่ในภาษา sql. ฉันคิดว่าเธอจะได้ gist:
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);
}