linq 比较请求和实体的正确方法

vsmadaxz  于 2022-12-06  发布在  其他
关注(0)|答案(1)|浏览(133)

我在管理器类中实现Get方法时遇到了问题我需要如何筛选以及在哪里编写筛选方法
简而言之-我有数据类Gym,存储库类和方法Find在其中。我在数据类中编写了方法- IsAppreciateToRequest(RequestName)来在管理器类中做类似的事情

public IEnumerable<GymDto> GetGyms(GetGymRequest request)
{
    return _gymRepository
           .Find(gym => gym.IsAppreciateToRequest(request))
           .AsEnumerable()
           .Select(GymDto.FromEntityToDto);
}

我认为这是shitcode,但也idk如何摆脱这一点,以及如何写它的正确方式(在此之前,我有Get方法像30-50行以上的每个管理器类)
IsAppreciateToRequest方法:

public bool IsAppreciateToRequest(GetGymRequest other)
        {
            return (string.IsNullOrEmpty(other.Name) || Name == other.Name)
                   &&  (string.IsNullOrEmpty(other.Location) || Location == other.Location) 
                   && (other.SectionRequest == null || Sections.All(section => section.IsAppreciateToRequest(other.SectionRequest)));
        }
whlutmcx

whlutmcx1#

可以使用LINQKit将表达式树注入到过滤器中,需要配置DbContextOptions

builder
    .UseSqlServer(connectionString) // or any other provider
    .WithExpressionExpanding();     // enabling LINQKit extension

您的类应该使用返回Expression<Func<>>的静态函数进行扩展,当前方法应该具有ExpandableAttribute
例如:

public class Gym
{
    [Expandable(nameof(IsAppreciateToRequestImpl))]
    public bool IsAppreciateToRequest(GetGymRequest other)
    {
        return (string.IsNullOrEmpty(other.Name) || Name == other.Name)
                && (string.IsNullOrEmpty(other.Location) || Location == other.Location) 
                && (other.SectionRequest == null || Sections.All(section => section.IsAppreciateToRequest(other.SectionRequest)));
    }

    private static Expression<Func<Gym, GetGymRequest, bool>> IsAppreciateToRequestImpl()
    {
        // first parameter is current object
        return (gym, other) => (string.IsNullOrEmpty(other.Name) || gym.Name == other.Name)
                && (string.IsNullOrEmpty(other.Location) || gym.Location == other.Location) 
                && (other.SectionRequest == null || gym.Sections.All(section => section.IsAppreciateToRequest(other.SectionRequest)));
    }
}

// the same technique as in Gym class
public class Section
{
    [Expandable(nameof(IsAppreciateToRequestImpl))]
    public bool IsAppreciateToRequest(GetSectionRequest other)
    {
        return // unknown;
    }

    private static Expression<Func<Section, GetSectionRequest, bool>> IsAppreciateToRequestImpl()
    {
        // first parameter is current object
        return (section, other) => // unknown;
    }
}

然后LINQKit将扩展静态方法返回的表达式,并将条件注入 predicate 。
同样的方法可以用于将实体投影到DTO。类似于我的答案here,它也显示了LINQKit的已知替代方案。

相关问题