简体   繁体   English

MVC,实体框架-是否有更好的方法来过滤项目?

[英]MVC, Entity Framework - Is there a better way to filter items?

I'm using a separate class to keep the filter options: 我正在使用一个单独的类来保留过滤器选项:

    public class FilterViewModel
    {
        public string UserName { get; set; }

        public int? TownId { get; set; }
        ...
     }

In the action I use a predicate which takes the filter as a parameter.That way the "Where" method returns IEnumerable instaed of IQuerable: 在操作中,我使用了一个谓词,该谓词将过滤器作为参数。这样,​​“ Where”方法将返回IQuerable的IEnumerable instaed:

    public ActionResult FilterProfiles(FilterViewModel filter)
    {
       var profiles = this.Data.Profiles.All()
            .Where(Predicate(filter)) 
            .OrderBy(p => p.ProfileUser.UserName).AsQueryable()
            .Project()
            .To<ProfileViewModel>()
            .ToList();
      }

    private static Func<UserProfile, bool> Predicate(FilterViewModel f)
    {
       return p => (CompareFilter(p, f));
    }

    private static bool CompareFilter(UserProfile profile, FilterViewModel filter)
    {
        if (filter.FirstName != null)
        {
            if (profile.FirstName != null)
            {
                if (profile.FirstName.CompareTo(filter.FirstName) != 0)
                {
                    return false;
                }
            }
       ...
      }

This worked until in ProfileViewModel I implemented database DateTime? 这一直有效,直到在ProfileViewModel中我实现了数据库DateTime? operation in the mapping: 映射中的操作:

    public class ProfileViewModel : IHaveCustomMappings
    {
        ...

        public bool IsUserOnline { get; set; }

        ...

        public void CreateMappings(IConfiguration configuration)
        {
            configuration.CreateMap<UserProfile, ProfileViewModel>()
                .ForMember(m => m.IsUserOnline, opt => opt.MapFrom(p =>
                   DbFunctions.DiffMinutes(p.ProfileUser.LastActionTime, DateTime.Now) < 5 ? true : false))
        }
    }

Then on the "Where" method in the action an error appears: 然后在操作中的“ Where”方法上出现错误:

[NotSupportedException: This function can only be invoked from LINQ to Entities.] System.Data.Entity.DbFunctions.DiffMinutes(Nullable 1 timeValue1, Nullable 1 timeValue2) +56 [NotSupportedException:此函数只能从LINQ到Entities调用。] System.Data.Entity.DbFunctions.DiffMinutes(可空1 timeValue1, Nullable 1 timeValue2)+56

I'm also wondering does in this case, IEnumerable "Where" copys all the database items in the memory and then filters them? 我也想知道在这种情况下IEnumerable“哪里”会复制内存中的所有数据库项,然后对其进行过滤吗?

Thanks in advance! 提前致谢!

EF expects Expression<Func<T,bool>> , but you are returning Func<T,bool> EF期望Expression<Func<T,bool>> ,但是您要返回Func<T,bool>

You have to change it to following 您必须将其更改为以下内容

private static Expression<Func<UserProfile, bool>> 
    Predicate(FilterViewModel f)
{
   return CompareFilter(f));
}

private static Expression<Func<UserProfile, bool>>
    CompareFilter(FilterViewModel filter)
{
    if (filter.FirstName != null)
    {
       return p => p.FirstName == filter.FirstName;
    }
   ...

   // this means nothing to compare, 
   // return all records...
   return p => true;
}

In case if you want to apply multiple filters, then you will have to filter IQueryable itself. 如果要应用多个过滤器,则必须过滤IQueryable本身。

private static IQueryable<UserProfile> 
    Predicate(IQueryable<UserProfile> q, FilterViewModel f)
{

    if (filter.FirstName != null)
    {

        q = q.Where( p => p.FirstName == filter.FirstName );
    }

    if (filter.LastName != null)
    {

        q = q.Where( p => p.LastName == filter.LastName );
    }
   ...

   // return all records...
   return q;
}

In order to run SQL and related operations on server, you have to apply filter on IQueryable which will be executed on server, instead of loading all them locally and then try to filter it. 为了在服务器上运行SQL和相关操作,您必须在将在服务器上执行的IQueryable上应用过滤器,而不是在本地加载所有过滤器然后尝试对其进行过滤。

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

相关问题 实体框架-急切模式-是否有更好的方法来过滤子关联? - Entity Framework - Eager mode - Is there a better way to filter child associations? 有没有更好的方法在实体框架中选择多行? - Is there a better way to select multiple rows in Entity Framework? 使用Entity Framework联接表的更好方法 - Better way to join tables with Entity Framework 有没有办法在Entity Framework中生成更好的查询 - Is there a way to generate a better query in Entity Framework 实体框架中按权限筛选行的最佳方法 - best way to filter rows by permission in Entity Framework 播种点网核心实体框架数据库的更好方法? - Better way to Seed a Dot Net Core Entity Framework Database? 有没有比使用Entity Framework + IDataErrorInfo更好的方法来实现模型验证? - Is there a better way to implement model validation with Entity Framework+IDataErrorInfo than this? 在实体框架4.1中,是否有更好的方法使用URL查找子页面? - In entity framework 4.1, Is there a better way to find subpages using a URL? 实体框架中哪种条件实现方法具有更好的性能? - Which way of implemeting conditions in Entity Framework has a better performance? 有没有更好的方法来概括具有相同属性的 dbSet - Entity Framework - Is there a better way to generalize dbSet with the same attribute - Entity Framework
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM