तो अपने डेटाबेस में एक मेज के साथ भरा 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] अद्वितीय है । इस का उपयोग एक प्राथमिक कुंजी
में इकाई की रूपरेखा स्तंभ तालिकाओं के द्वारा प्रतिनिधित्व कर रहे हैं गैर-आभासी गुण है । आभासी गुणों को प्रतिबिंबित संबंधों तालिकाओं के बीच (एक-से-कई, कई-कई)
नोट: एक विदेशी कुंजी है एक असली स्तंभ किसी तालिका में है, इसलिए एक विदेशी कुंजी है, गैर आभासी.
विन्यस्त करने के लिए कई-कई, आप का उपयोग कर सकते हैं धाराप्रवाह एपीआई:
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,
...
}
}
समाधान के बिना सामान्यीकृत डेटाबेस
यदि आप वास्तव में मना नहीं कर सकते हैं, अपनी परियोजना के नेता है कि एक उचित डेटाबेस को रोकने जाएगा का एक बहुत भविष्य में समस्याओं पर विचार करने के लिए बनाने के लिए एक एसक्यूएल पाठ में है कि उचित डाक के लिए आप.
अपने DbContext वर्तमान का प्रतिनिधित्व करता है के कार्यान्वयन के अपने डेटाबेस. यह वर्णित तालिकाओं और संबंधों तालिकाओं के बीच. जोड़ने के लिए एक विधि लाने के पदों के एक उपयोगकर्ता करने के लिए लगता है मुझे एक कानूनी विधि के लिए DbContext.
मेरा एसक्यूएल थोड़ा ज़ंग खाया हुआ है, आप जानते हैं जिस तरह से बेहतर की तुलना में मैं कैसे यह करने के लिए में 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);
}