4

開発中のWebアプリケーション(ASP.Net MVC)には、telerikグリッドを使用しています。グリッドは私のリストのIQueryableにバインドされています。これは大きなテーブルであり、telerikがリストにフィルターを適用してから、この結果を実行し、(結合されたテーブルで)10,000行をダウンロードしないようにします。フィルタでは、行のみを使用します。

グリッドのフィルター/順序を使用しています(このページでは本当に必要です。これは重要な機能の1つです)。

メインの列の1つ(データの種類を決定する)は列挙型です。

問題は、"Specified type member is not supported in linq to entities"フィルター/ソートしようとするとすぐに取得することです。

idを使用すると、filters / order byがintになり、ユーザーが外部テーブルのIDを知っているとは期待できないため、列挙型(マップされたintではなく)にバインドする必要があります。

すべてのグリッドパラメーター(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();
}

アップデート :

少なくとも1つの並べ替え順序を適用する場合は、次のようなものを使用できます。

 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
    }

もちろん、DB内の実際のデータ(マップされたint)を確認し、新しい順序に一致するように更新する必要があります(影響なしに列挙型の順序を変更することはできません)。また、既存の列挙値の間に値を挿入するたびに、これを行う必要があります。

または、次のEF / linq / c#バージョンを待ちます。これはlinq2entitiesで列挙型サポートが必要です。

于 2012-05-09T09:58:17.440 に答える