存储在Dictionary中的C#“Anonymous”类型的List

时间:2014-08-27 13:40:45

标签: c# dictionary asp.net-mvc-5 anonymous-types

我得出的结论可能是不可能的,但我想在完全放弃之前我会问这里。我正在寻找的是类似的东西:

Dictionary<string, List<T>> FilterLists { get; set; }

我希望能够存储可能需要的任意数量的列表,然后能够通过字符串Key&#39; index&#39;来找到它们。

我需要这样的原因是因为某些约束必须存储它的位置,并且不可能将List键入任何特定的东西,因为它无法看到我想要的对象类型放在那里。即使我可以看到对象类型,这也会降低其在其他项目中的可重用性,而其他人可能想要放在那里的内容可能会以不同的方式构建,我试图尽可能地使其可重用。

我发现了这篇文章:Declaration of Anonymous types List,但这并不适用于我尝试做的事情。

此外,这必须在Interface类中进行,因此它只是一个定义。

使用说明: 这特别适用于MVC5应用程序中的分页结果。返回结果列表,但我还想要某些标题列中的下拉过滤器(就像您在Excel过滤列中看到的那样)。

我试图尽可能避免使用ViewBag,原因有几个。我不喜欢用它。 我的分页&#34;代码位于一个名为Common的项目中,以使其可以访问我的Web项目和我的服务项目(业务逻辑层)。我正在使用的模型和ViewModel存储在Service中,因此我无法使用Common referencing Service,因为Service已经引用了自定义IPagedList构造的Common,用于定义将要分页的对象列表。 IPagedData包含一组用于过滤,排序和分页结果集的属性。创建了LINQ扩展(.ToPageList)以便于对数据进行这些操作。这个过程涉及几个对象,但我至少会发布IPagedData(我希望这个字典去的地方)。

using System.Collections.Generic;

namespace GameKeyExchange.Common.Pagination
{
    public interface IPagedData
    {
        Dictionary<string, List<T>> FilterLists { get; set; }

        /// <summary>
        /// Stores pagination and sort information.
        /// </summary>
        PageSortCriteria Criteria { get; set; }

        /// <summary>
        /// Total number of subsets within the superset.
        /// </summary>
        int PageCount { get; }

        /// <summary>
        /// Total number of objects contained within the superset.
        /// </summary>
        int TotalItemCount { get; }

        /// <summary>
        /// Zero-based index of this subset within the superset.
        /// </summary>
        int PageIndex { get; }

        /// <summary>
        /// One-based index of this subset within the superset.
        /// </summary>
        int PageNumber { get; }

        /// <summary>
        /// Maximum size any individual subset.
        /// </summary>
        int PageSize { get; }

        /// <summary>
        /// Returns true if this is NOT the first subset within the superset.
        /// </summary>
        bool HasPreviousPage { get; }

        /// <summary>
        /// Returns true if this is NOT the last subset within the superset.
        /// </summary>
        bool HasNextPage { get; }

        /// <summary>
        /// Returns true if this is the first subset within the superset.
        /// </summary>
        bool IsFirstPage { get; }

        /// <summary>
        /// Returns true if this is the last subset within the superset.
        /// </summary>
        bool IsLastPage { get; }
    }
}

理想情况下,代码实现在我的服务中看起来像这样:

var list = data.ClaimedKeys.Where(m => m.UserId == UserId).Select(m => new ClaimedKeysViewModel()
{
    KeyTypeId = m.GameKey.GameKeyGroup.KeyTypeId,
    PlatformId = m.GameKey.GameKeyGroup.PlatformId,

    Value = m.GameKey.Value,
    KeyType = m.GameKey.GameKeyGroup.KeyType.Name,
    Game = m.GameKey.GameKeyGroup.Game.Name,
    Platform = m.GameKey.GameKeyGroup.Platform.Name,
    Expiration = m.GameKey.GameKeyGroup.Expiration
})

list.FilterLists.Add("KeyTypeFilter", list.Select(m => new List<SelectListModel>()
{
    Value = m.KeyTypeId,
    Text = m.KeyType
});

list.FilterLists.Add("PlatformFilter", list.Select(m => new List<SelectListModel>()
{
    Value = m.PlatformId,
    Text = m.Platform
});

list.OrderBy(string.Format("{0} {1}", sort, order))
    .ToPagedList<ClaimedKeysViewModel>(pageNumber, pageSize);

这样,我可以获取服务中的paginate数据列表,构建我的分页,还包括任何数量的过滤器列表,这些过滤器列表将被发送回控制器。控制器接收:IPageList,它是数据列表,包括用于排序和过滤的这些额外属性。它们与数据列表一起传递的原因是,当通过单击标题或更改页面进行求助时,您确切地知道您所在的页面以及当它获取每个页面或度假时的排序的当前状态。 / p>

否则,我必须对数据库进行二次调用以构建我的过滤器并将其作为ViewBag对象发送。此外,因为初始View和刷新方法(在初始加载用于求助或导航页面之后使用),我必须在两个方法中使用相同的代码来构建列表。如果我可以在生成列表的服务方法中使用它,则只需在那里完成;无论如何,两种控制器方法中已经调用的方法相同。

希望能更好地澄清用例。

2 个答案:

答案 0 :(得分:1)

如果您在编译时不知道类型T,那么为什么首先需要泛型?

如果您只是想在不同的项目中重复使用它,那么在您的界面中添加一个通用约束:

public interface IFilters<T>
{
    Dictionary<string, List<T>> FilterLists { get; set; }
}

答案 1 :(得分:0)

除了使用List<object>之外,可能有助于使您的界面具有通用性:

public interface MyInterface<T>
{
  Dictionary<string, List<T>> FilterLists { get; set; }
}