简体   繁体   中英

Linq to entities - filter on a child table via include

I have a one to many r/ship between two tables. I am using Entity Frameworks 6. Table 1 is called "Vote" and table 2 is "VoteInfo". The Vote table has an attribute called "VoteYear" and the VoteInfo table has an attribute called "VoterId". There could be many vote records in a given year but a voter can only vote once per a vote record. My goal is to return a list of all votes in a year that a voter has voted on. I want to include the information from the VoteInfo table as part of this list. This is how I want to return my result:

 <Vote> <VoteDate>5/21/2015</VoteDate> <VoteYear>2015</VoteYear> <VoteInfo> <VoterId>1</VoterId> <VoteValue>Yes</VoteValue> </VoteInfo> </Vote> <Vote> <VoteDate>4/21/2015</VoteDate> <VoteYear>2015</VoteYear> <VoteInfo> <VoterId>1</VoterId> <VoteValue>Yes</VoteValue> </VoteInfo> </Vote> <Vote> <VoteDate>3/21/2015</VoteDate> <VoteYear>2015</VoteYear> <VoteInfo> <VoterId>1</VoterId> <VoteValue>No</VoteValue> </VoteInfo> </Vote> 

I tried this but not working:

public IQueryable<Vote> GetVoterRecord(string Year, string VoterId)
{
   return _dbCtx.Vote.Include("VoteInfo")
  .Where(v => v.VoteYear == Year && v.VoteInfo.Any(i => i.VoterId == VoterId));
}

The sample code satisfying OP's conditions is the following.

public class VotesContext : DbContext {
        public DbSet<Vote> Votes { get; set; }
        public DbSet<VoteInfo> VoteInfos { get; set; }
    }

    public class Vote {
        public int VoteId { get; set; }
        public string VoteYear { get; set; }
        public virtual ICollection<VoteInfo> VoteInfo { get; set; }
    }

    public class VoteInfo {
        public int VoteInfoId { get; set; }
        public string VoterId { get; set; }
    }

Then the code

            var v1 = db.Votes.Add(new Vote { VoteYear = "2001", });
            var v2 = db.Votes.Add(new Vote { VoteYear = "2001", });
            var v3 = db.Votes.Add(new Vote { VoteYear = "2002", });
            var v4 = db.Votes.Add(new Vote { VoteYear = "2003", });

            v1.VoteInfo = new List<VoteInfo> { new VoteInfo { VoterId = "1", }, new VoteInfo { VoterId = "3", }, }; 
            v2.VoteInfo = new List<VoteInfo> { new VoteInfo { VoterId = "1", }, new VoteInfo { VoterId = "4", }, }; 
            v3.VoteInfo = new List<VoteInfo> { new VoteInfo { VoterId = "2", }, }; 
            //v1.VoteInfo = new List<VoteInfo> { new VoteInfo { VoterId = "3", }, }; 
            //v2.VoteInfo = new List<VoteInfo> { new VoteInfo { VoterId = "4", }, };

            db.SaveChanges();

            // Each record corresponds to a vote in 2001 where voter #1 has voted.
            // VoteInfo for each voter in this vote is included.
            var votesIn2001With1 = db.Votes
                .Where(x1 => 
                    x1.VoteYear == "2001" &&
                    x1.VoteInfo.Any(x2 => x2.VoterId == "1"))
                .Select(x => new {
                    vote = x,
                    voteInfo = x.VoteInfo.ToList(),
                })
                .ToList();

            // Each record corresponds to a vote in 2001 where voter #1 has voted.
            // VoteInfo only for voter #1 is included.
            var votesOf1In2001 = db.Votes
                .Where(x1 => 
                    x1.VoteYear == "2001" &&
                    x1.VoteInfo.Any(x2 => x2.VoterId == "1"))
                .Select(x1 => new {
                    vote = x1,
                    voteInfo = x1.VoteInfo
                        .Where(x2 => x2.VoterId == "1")
                        .ToList(),
                })
                .ToList();

does exactly the necessary things.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM