2017-11-20 4 views
0

私はこのような複数の投票と一見単純なポストのテーブルを持っている:のIQueryable二つのテーブル

ポスト:

namespace Api.Models 
{ 
    public class Post 
    { 
     public int id { get; set; } 
     public bool deleted { get; set; } 
     public virtual User creator { get; set; } 

     (...) 

     public virtual ICollection<Vote> votes { get; set; } 
    } 
} 

投票:

namespace Api.Models 
{ 
    public class Vote 
    { 
     public int id { get; set; }  
     public bool seen { get; set; } = false; 

     (...) 

     [JsonIgnore] 
     [IgnoreDataMember] 
     public virtual ICollection<Post> post { get; set; }  
    } 
} 

これは、生成しましたVote_idとPost_idを外部キーとしてSQLデータベース内のVotePostテーブル。

投稿が0票の場合、またはすべての票が表示されている場合は、p.creator.user_idで投稿に接続されている==偽を表示する投票を取得しようとしています。それから私は==ポスト要素

ポストが複数票のオブジェクトを持っていると私はすべてのvote.seenをフィルタリングする方法がわからない返すことを事前に偽

 IQueryable<Post> postQuery = (from p in db.Posts where 
             p.deleted == false && 
             p.creator.user_id == user_id && 

             // all p.votes object seen == false ? 

             select p); 

感謝する必要はありませんあなただけのAll() LINQメソッドを使用することができます任意の助け

答えて

1

あなたにはユーザー、投稿、投票があります。

クリエイターと投稿の間にはone-to-many relationがあります。すべてのクリエイターはゼロ以上の投稿を持ち、すべての投稿は正確に1つのクリエイターに属します。

a many-to-many relation between Posts and Votes:すべての投稿は0件以上の投票数を持ち、すべての投票数は0件以上の投稿数です。

なぜ標準エンティティフレームワークの慣習から逸脱し、クラス定義の外部キーを省略したのか分かりません。これにより、クエリが難しくなります。しかし、私たちはあなたが設計したものと関係があります。

あなたが書いた:

をポストが0票 またはすべての票を持っている場合、私は、唯一のp.creator.user_idでポストに接続されている 偽==見投票を取得しようとしています見られています。

は、ユーザーのプライマリキーである変数のuser_idを考える:それから私は、私は、これは言うのは難しいと少しあいまいな方法ですguesポスト要素

を返す必要はありません。表示されていないすべての投票結果が表示され、主キーuser_Idを持つ作成者の投稿を持つクエリを私に与えてください。あなたのクラスで外部キーを含めたい場合

var result = dBContext.Votes 
    .Where(vote => !vote.Seen 
     && vote.Posts.Any(post => post.Creator.user_id == user_id); 

それがさらに簡単だっただろう:

class User 
{ 
    public int Id {get; set;} // primary key 
    // a User has zero or more Posts: 
    public virtual ICollectioins<Post> Posts {get; set;} 
    ... 
} 
class Post 
{ 
    public int Id {get; set;} // primary key 

    // Every Post belongs to exactly one User via foreign key 
    public User User {get; set;} 
    public int UserId {get; set;} 

    // a Post has zero or more Votes (many-to-many) 
    public virtual ICollection<Vote> Votes{get; set;} 
    ... 
} 

class Vote 
{ 
    public int Id {get; set;} // primary key 
    // A vote is for zero or more Posts (many-to-many) 
    public virtual ICollection<Post> Posts{get; set;} 

    public bool Seen {get; set;} 
} 

それはあなたが異なった性質のいくつかを命名していますが、要点を得ることかもしれません。

あなたのクエリがさらに簡単で、ポストのユーザへの外部キーが含まれていたら:

var result = dBContext.Votes 
    .Where(vote => !vote.Seen 
     && vote.Posts.Any(post => post.userid == user_id); 

アドバイス:あなたが主のための非従来型の名前を使用するように、entity framework code first conventionsから逸脱を考えるたびにキーとfoerignキー、ICollectionのプロパティなどの非従来型の名前を使用して2回考える:この偏差は本当に必要ですか?

偏在とは、流暢なApiまたは属性の必要性を意味します。メンテナンス:他の人は、あなたが意味するものをすぐには見ません。クエリが難しくなる可能性があります。

+0

ありがとうございます。おそらくここではデータベースの設定に間違いがありました。投稿は複数の票を持つことができますが、投票は1つの投稿にのみ関連付ける必要があります。だから私は投票は本当にちょうどpost_idの外部キーを持っている必要がありますね..再びありがとう – ganjan

0

:あなたがそのように試みることができる

IQueryable<Post> postQuery = (from p in Posts 
           where p.deleted == false 
           && p.creator.user_id == user_id 
           && p.votes.All(v => !v.seen) 
           select p).AsQueryable(); 
1

を。

IQueryable<Post> postQuery = (from p in db.Posts 
        where 
        p.deleted == false && 
        p.creator.user_id == user_id && 
        (p.votes == null || !p.votes.Any(v => v.seen == true)) 
        select p);