为什么我不能遍历匿名类型

时间:2018-07-17 16:04:37

标签: c# linq

ControllerAction:

{

    AddLeadSourcesModel model = new AddLeadSourcesModel();
    List<LeadSourceModel> models = LeadSourceModel.Get()
                                                  .Where(c => c.Active == true)
                                                  .ToList();
    var A = LeadSourceModel.GetSubLeadSources(leadSourceID);
    model.LeadSources = new SelectList(
        LeadSourceModel.Get().Where(c => c.Active == true), 
        "LeadSourceID", 
        "Name", 
        models.Where(c => c.LeadSourceID == leadSourceID).FirstOrDefault().LeadSourceID
    );

    model.SubLeadSources = new SelectList(A, "LeadSourceID", "Name");

    var flattenedData = model.SubLeadSources.SelectMany(subLead => model.LeadSources, (n, a) => new { n,a });

    return PartialView("_AddLeadSources", flattenedData.ToList());

}

查看:

<table>
    <tr>
        <td>Lead Source</td>
        <td>Sub Lead Source</td>
        <td>Action</td>
    </tr>
    @foreach(var item in Model)
    {
    <tr>
        <td>@item.a</td>
        <td>@item.n</td>
        <td><a href="#">Remove</a></td>
    </tr>
    }
</table>

我的问题是,当我到达部分代码时,它说它期望使用其他类型,但是我没有告诉它一种类型。而且我从技术上不知道类型coz是不是很麻烦

如何使它工作?

1 个答案:

答案 0 :(得分:0)

您已经在某个地方定义了类PartialView,该类带有一个带有两个参数的构造函数。

A,您忘了给我们提供此构造函数的签名,但是我认为第一个是字符串,第二个是某些已定义类型的列表/序列/集合。我期望像这样:

class PartialView
{
     public PartialView(string txt, List<MyType> items) {...}
}

如果要使用此构造函数,则必须提供List<MyType>。为此,请在创建FlattenedData之前使用Select

List<MyType> flattenedData = model.SubLeadSources
    .SelectMany(subLead => model.LeadSources, (n, a) => new { n,a })
    .Select(item => new MyType()
    {
        // fill the MyType properties, something like:
        N= item.n
        A = item.a,
    };

现在您可以使用构造函数了。

PartialView partialView = new PartialView("_AddLeadSources", flattenedData);

扩展功能

如果您经常将某些匿名类型转换为MyType和PartialView的序列,请考虑创建一个扩展函数,该扩展函数将使用任何(匿名)类型的序列,字符串和两个lambda表达式作为输入告诉您匿名类型的哪些值是A和N。

请参见extension methods demystified

我们已经知道MyType具有A和N之类的属性,您想在其中放置匿名a和n。假设它们具有非通用类型Atype和Ntype,例如int或DateTime或MyElaborateClass,像这样:

class MyType
{
     public Atype A {get; set;}
     public Btype B {get; set;}
}

PartialView的扩展类:

static class PartialViewExtension
{
    // Creates one PartialView object from a sequence of MyType objects and a text
    public static PartialView ToPartialView(this IEnumerable<MyType> source, string text)
    {
         return  new PartialView(text, source.ToList());
    }

    // uses the source + predicates to create a sequence of MyType objects
    public static IEnumerable<MyType> ToMyType<TSource>(this IEnumerable<TSource> source,
        Func<TSource, Atype> aSelector,
        Func<TSource, Ntype> nSelector)
    {
         return source.Select(sourceItem => new MyType()
         {
              A = aSelector(sourceItem),
              B = bSelector(sourceItem),
         });
    }
}

用法将是:

var flattenedData = model.SubLeadSources
    .SelectMany(subLead => model.LeadSources, (n, a) => new { n,a });

PartialView partialView = flattenedData
      .ToMyType(flattenedInput => flattenedInput.n,
                flattendInput => flattenedInput.a)
      .ToPartialView("_AddLeadSources");

现在我们已经在创建扩展功能,将这两个功能合并为一个,将调用另外两个功能:

public static PartialView ToPartialView<TSource>(this IEnumerable<TSource> source,
    string text,
    Func<TSource, Atype> aSelector,
    Func<TSource, Ntype> nSelector)
{
    return source.ToMyType(aSelector, bSelector).ToPartialView(text);
}

用法:

var flattenedData = model.SubLeadSources
    .SelectMany(subLead => model.LeadSources, (n, a) => new { n,a });

PartialView = flattenedData.ToPartialView("_AddLeadSources",
    flattenedInput => flattenedInput.a,
    flattenedInput => flattenedInput.n);