c# - 传递连接表以查看模型 Asp.Net Core
问题描述
我有 2 个通过 linq 查询加入的表:
var catData = from c in _context.ProductCategory
join d in _context.ProductCategoryData
on c.Id equals d.ProductCategoryId into g
from gg in g.DefaultIfEmpty()
select new { c.Id, c.Name, gg.Path };
我想将此查询的结果作为模型传递给查看。问题是该视图需要我传递的模型的强烈指定类型。
我听说可以引入另一个包含 2 个表模型的类,然后将 2 个表加入这个类。但是,在我看来,它效率不高,因为我将始终拥有两个表中的所有列,而我只需要特定的列。
我想到的另一个选择 - 使用如下所示的 ExpandoObject:
dynamic model = new ExpandoObject();
model = catData.ToList();
return View("Categories", model);
然后像这样访问视图中的动态对象:
@model dynamic;
@foreach (var i in Model)
{
<img src="@i.Path">
<p>@i.Name</p>
}
但是,这会引发模型对象不包含路径或名称的错误。
有没有其他方法可以解决这个问题?
解决方案
你需要的是一个IEnumerable<dynamic>
not a dynamic
。dynamic
仅用作暴露属性/方法的对象,不能是IEnumerable
任意对象。如您所见,ExpandoObject
它实际上是一个IEnumerable
键值对(成员名称和成员值之间的映射)。但这不是IEnumerable
你想要的。
这段代码:
dynamic model = new ExpandoObject();
model = catData.ToList();
实际上会将您设置model
为{ c.Id, c.Name, gg.Path }
. 所以它不像你想象的那样动态。
以下是如何构建一个IEnumerable<dynamic>
:
var model = catData.Select(e => {
dynamic o = new ExpandoObject();
o.Id = e.Id;
o.Name = e.Name;
o.Path = e.Path;
return o;
});
该模型是真实的IEnumerable<dynamic>
,它现在应该可以工作。
您还可以编写扩展方法将法线转换IEnumerable<T>
为IEnumerable<dynamic>
使用这种特殊情况,如下所示:
public static class DynamicEnumerableExtensions {
public static IEnumerable<dynamic> AsDynamic<T>(this IEnumerable<T> items) {
var props = typeof(T).GetProperties();
foreach(var item in items)
{
var o = new ExpandoObject();
//set properties for the dynamic item
foreach(var prop in props)
{
o.TryAdd(prop.Name, prop.GetValue(item));
}
yield return o;
}
}
}
并像这样使用它:
var model = catData.AsDynamic();
使用这种方便的方法,您不必每次都手动重写逻辑,例如任意匿名对象的新列表(具有未知数量的属性)。