Takže vaša databáza obsahuje tabuľky plnené Posts
. Každý Post
zdá sa pridal nula alebo viac (možno jeden alebo viac) Používateľov. Zdá sa mi, že máte tabuľku Users
. Každý User
bol vyslaný nula alebo viac Posts
.
Zdá sa mi, že tam je veľa-to-many vzťah medzi Users
a Posts
: Každý Užívateľ má publikované nula alebo viac Miest; každý Príspevok bol zverejnený na nulu (jeden?) alebo viac Užívateľov.
Za normálnych okolností v databáze by ste realizovať many-to-many vzťah s osobitnej tabuľky: spojovacej tabuľky.
Nemáte pomocou spojovacej tabuľky. Databáza nie je normovaná.
Možno, že váš súčasný problém sa dá vyriešiť bez zmeny databázy, ale vidím, toľko problémov budete musieť vyriešiť, možno nie teraz, ale v blízkej budúcnosti: aké obrovské úsilie by musíte urobiť, ak chcete zmazať používateľa? Ako dosiahnuť, aby sa všetky Príspevky používateľa, [10] bol vyslaný" A čo ak si Užívateľ [10] nechce byť uvedené už v publikácii zoznam Post [23]? Ako zabrániť tomu, aby Používateľ [10] je uvedená dvakrát v Príspevku[23]:
UserIds = 10, 3, 5, 10, 7, 10
Normalizovať databázy
Zvážiť možnosť aktualizácie databázy pomocou spojovacej tabuľky a zbaviť string stĺpec Post.UserIds
. To by vyriešiť všetky tieto problémy naraz.
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;}
}
A spojovacej tabuľke:
public UsersPost
{
public int UserId {get; set;}
public int PostId {get; set;}
}
Upozornenie: [UserId, PostId] je jedinečný. Použite tento primárny kľúč
V účtovnej jednotky rámec stĺpcov tabuliek sú zastúpené non-virtuálne vlastnosti. Virtuálne vlastnosti odrážajú vzťahy medzi tabuľkami (one-to-many, many-to-many)
Poznámka: cudzí kľúč je skutočný stĺpec v tabuľke, teda cudzí kľúč je non-virtuálne.
Ak chcete nakonfigurovať many-to-many, môžete použiť Plynule 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});
}
Späť na váš problém
Akonáhle ste implementovali spojovacej tabuľke vaše údaje žiadosť bude jednoduché:
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(),
});
Alebo, ak nechcete, aby sa údaje používateľa, začať s Príspevky:
var postsOfUser = dbContext.Posts
.Where(post => post.Users.Any(user => user.Id == userId))
.Select(post => new {...});
Niektorí ľudia nemajú radi, ak chcete použiť virtuálne ICollections, alebo ich použite verziu entity framework, ktorý nepodporuje tento. V tomto prípade, budete musieť urobiť, je Pripojiť sa sami seba:
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,
...
}
}
Riešenie bez normovaná databázy
Ak sa naozaj nemôžem presvedčiť vášho projektu leader že riadne databázy bude zabrániť mnohým problémom v budúcnosti, zvážte vytvorenie SQL text, ktorý si riadne príspevky pre vás.
Vaše DbContext predstavuje súčasná implementácia databázy. To popísané tabuľky a vzťahy medzi tabuľkami. Pridaním metóda na zisťovanie Príspevky používateľa, zdá sa mi, dôveryhodne metóda pre DbContext.
My SQL je trochu hrdzavý, budete vedieť lepšie ako ja, ako sa to v SQL. Myslím, že dostanete podstata:
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);
}