4

对于开发中的 Web 应用程序(ASP.Net MVC),我使用的是 Telerik 网格。网格绑定到我的列表的 IQueryable,因为它是一个大表,我希望 Telerik 在列表上应用它的过滤器,然后执行这个结果,而不是下载 10'000 行(带有连接的表),然后使用过滤器,仅使用行。

我正在使用(我真的需要它用于此页面,它是关键功能之一)网格的过滤器/顺序。

主要列之一(确定数据的种类)是枚举。

问题是我一"Specified type member is not supported in linq to entities"尝试过滤/排序就得到了。

我必须将它绑定到枚举(而不是映射的 int)上,因为如果我使用 id,filters/order by 将在一个 int 上,我不能指望用户知道外部表的 id。

我只是无法再次实现自己的所有网格参数(位于 url 中)(我假设,要么我什么都做,要么什么都不做)并正确过滤,正确排序)。

您有解决方法的想法吗?

4

2 回答 2

5

我不知道你的实体模型是什么样子,但我假设你有这样的模型:

public partial class Project
{    
    public int Id { get; set; } 
    public string Name { get; set; }
    public int Status { get; set; }
}

并且 Status 属性代表你的枚举值,那么你有这个枚举:

public enum ProjectStatuses
{
    Current = 1,
    Started = 2,
    Stopped = 3,
    Finished = 4,
}

然后像这样创建新的 ViewModel:

public class ProjectDetails
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Status { get; set; }
        public ProjectStatuses StatusValue { get { return (ProjectStatuses) Status; } }
        // This property to display in telerik ClientTemplate
        public string StatusName { get { return Enum.GetName(typeof (ProjectStatuses), Status ); } }            
    }

因为我喜欢扩展方法,所以我会添加这个:

public static class ModelListExtensions
{
        public static IQueryable<ProjectDetails> ToViewModelDetails(this IQueryable<Project> modelList)
        {
            return modelList.Select(m => new ProjectDetails
                                             {
                                                 Id = m.Id,
                                                 Name = m.Name,
                                                 Status = m.Status,
                                              };
         }
}

更新 :

这是控制器

    public ActionResult Index()
    {
        int total;
        var viewModel = getGridList(out total);
        ViewBag.Total = total;
        return View(viewModel);
    }

    //this Action to get ajax pages
    [GridAction(EnableCustomBinding = true)]
    public ActionResult ReGetIndex(GridCommand command, int roleId)
    {
        int total;
        var list = getGridList(out total, roleId, command);
        return View(new GridModel {Data = list, Total = total});
    }


    private IEnumerable<ProjectDetails> getGridList(out int total, GridCommand command = null)
    {
        command = command ?? new GridCommand {Page = 1};
    foreach (var descriptor in command.SortDescriptors)
    {
        if (descriptor.Member == "StatusValue")
            descriptor.Member = "Status";

    }
    foreach (FilterDescriptor descriptor in command.FilterDescriptors)
    {
        if (descriptor.Member == "StatusValue")
            descriptor.Member = "Status";
    }

    var list = modelService.AllAsQuery()
            .ToViewModelDetails() // To convert it to our ViewModel if we have one
            .Where(command.FilterDescriptors);

    total = list.Count();

    return (IEnumerable<ProjectDetails>) list.Sort(command.SortDescriptors)
                                                  .Page(command.Page - 1, command.PageSize)
                                                  .GroupBy(command.GroupDescriptors).ToIList();
}

这就是视图

@model IEnumerable<ProjectDetails>
@{
    Html.Telerik()
        .Grid(Model)
        .Name("ProjectsGrid")
        .Sortable()
        .Filterable()
        .EnableCustomBinding(true)
        .DataBinding(dataBinding => dataBinding
                                        .Ajax()
                                        .Select("ReGetIndex", "Projects"))
        .Pageable(page => page.Style(GridPagerStyles.PageSizeDropDown | GridPagerStyles.NextPreviousAndNumeric).Total(ViewBag.Total))
        .Columns(column =>
                     {
                         column.Bound(m => m.Id).Hidden(true);
                         column.Bound(m => m.Name);
                         column.Bound(m => m.StatusValue).ClientTemplate("<#= StatusName #>");
                     })
        .Render();
}

更新 :

如果您想强制执行至少一种排序顺序,您可以使用如下内容:

 if (!command.SortDescriptors.Any())
 {
     command.SortDescriptors.Add(new SortDescriptor {Member = "YourDefaultProperty"});
 }
于 2012-05-12T02:15:39.260 回答
0

你真的没有选择(或者很少有恼人的选择)

您是否使用类而不是枚举(但如果您使用枚举,那是因为它更好)。

或者你“伪排序”你的枚举,并使用映射的 int。

public enum TT
    {
        Brown = 0,
        Green = 1
    }

当然,您必须检查数据库中的实际数据(映射的 int)并更新它们以符合新顺序(无法更改枚举顺序而不产生影响)。每次您想在现有枚举值之间插入一个值时,您都必须这样做。

或者你等待下一个 EF / linq / c# 版本,它应该在 linq2entities 中支持枚举

于 2012-05-09T09:58:17.440 回答