繁体   English   中英

实体框架:生成动态where子句并选择自定义列

[英]Entity Framework: generate dynamic where clause and select custom columns

我有3个表: PersonPersonFriendPersonGroup

使用LINQ,我想加入3个表,使用动态生成的where子句进行过滤,并选择具有展平行(展平的一对多关系表列)的自定义列。

伪SQL设计:

CREATE TABLE Person (int id, varchar socialclass, date createddate);
CREATE TABLE Person_Friend (int id, id personid references person.id, id friendpersonid references person.id, varchar friendtype);
CREATE TABLE Person_Group (int id, int memberid references person.id, varchar membershiplevel);

实体:

public class Person
{
    public int Id { get; set; }

    public string SocialClass { get; set; }

    public DateTime? CreatedDate { get; set; }

    public ICollection<PersonFriend> Friend { get; set; }

    public ICollection<PersonGroup> Group { get; set; }
}

public class PersonFriend
{
    public int Id { get; set; }

    public int PersonId { get; set; }

    public int FriendPersonId { get; set; }

    public string FriendType { get; set; }
}

public class PersonGroup
{
    public int Id { get; set; }

    public int MemberId { get; set; }

    public string MembershipLevel { get; set; }
}

查询语法LINQ:

var queryResult = from person in _context.Person
                join friend in _context.PersonFriend on person.Id equals friend.FriendPersonId
                join group in _context.PersonGroup on person.Id equals group.MemberId
                where (friend.PersonId == 1 && friend.FriendType == "type1") || (friend.PersonId == 3 && friend.FriendType == "type2") || ...
                select new { person.Id, person.SocialClass, person.CreatedDate, friend.FriendPersonId, friend.FriendType, group.Id, group.MembershipLevel };

注意where子句; 给定{ PersonId, FriendType }对象的列表,我想构建像上面的where子句。

由于无法计算query syntax LINQ的动态where子句,因此我尝试将其转换为Method syntax LINQ语句,以便可以利用PredicateBuilderhttp://www.albahari.com/nutshell/predicatebuilder.aspx ),但是在将多对多的对象选择到一个展平的对象期间,我遇到了问题。

var methodResult = _context.Person
                .Include(x => x.Friend)
                .Include(x => x.Group)
                .Select(person => new { person.Id, person.SocialClass, person.CreatedDate, person.friend.FriendPersonId, person.friend.FriendType, person.group.Id, person.group.MembershipLevel }); 

请注意,由于friend是ICollection,因此无法执行上述Select。

我也尝试使用不带where子句的上述query syntax LINQ语句,使其返回一个对象而不是一个匿名对象,然后使用谓词生成器调用方法.Where() 但是,生成的表达式会遇到LINQ => Entity Framework SQL conversion error并在应用程序中而不是DB中执行where

var queryResultWithoutWhere = from person in _context.Person
                join friend in _context.PersonFriend on person.Id equals friend.FriendPersonId
                join group in _context.PersonGroup on person.Id equals group.MemberId
                select new SelectedObject { PersonId = person.Id, SocialClass = person.SocialClass, CreatedDate = person.CreatedDate, FriendId = friend.FriendPersonId, FriendType = friend.FriendType, GroupId = group.Id, MembershipLevel = group.MembershipLevel };


var predicate = PredicateBuilder.New<SelectedObject>(false);

foreach (var searchObject in searchRequestObjects)
{
    predicate.Or(p => p.FriendPersonId == searchObject.FriendPersonId && p.FriendType == searchObject.FriendType);
}

var result = queryResultWithoutWhere.Where(predicate).ToList();

我觉得我已经尽力了,但似乎无法生成此SQL。 不得已的方法是编写一个原始SQL字符串,然后执行它,但是我真的很想让它与Entity Framework一起使用。

如何完成创建动态where子句,选择自定义展平对象并让实体框架生成SQL的工作?

您可以使用SelectMany展平集合:

var methodResult = Persons
                .Include(x => x.Friend)
                .Include(x => x.Group)
                .SelectMany(person =>
                    person.Friend.SelectMany(friend =>
                        person.Group.Select(group =>
                            new {
                                person.Id,
                                person.SocialClass,
                                person.CreatedDate,
                                friend.FriendPersonId,
                                friend.FriendType,
                                GroupId = group.Id,
                                group.MembershipLevel
                            }
                        )
                    )
                );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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