简体   繁体   English

传递连接表以查看为 model Asp.Net Core

[英]Passing joined table to view as model Asp.Net Core

I have 2 tables that I join via linq query:我有 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 };

I want to pass result of this query as model to view.我想将此查询的结果作为 model 传递给查看。 The issue is that view requires strongly specified type of model I'm passing.问题是视图需要强烈指定类型的 model 我正在传递。

I've heard that it's possible to introduce another class which will contain 2 table models and then join 2 tables into this class.我听说可以引入另一个 class,它将包含 2 个表模型,然后将 2 个表加入这个 class。 However, in my opinion it's not efficient since I will always have all columns from both tables while I need only particular columns.但是,在我看来,它效率不高,因为我将始终拥有两个表中的所有列,而我只需要特定的列。

Another option that came to my mind - to use ExpandoObject like below:我想到的另一个选择 - 使用如下所示的 ExpandoObject:

dynamic model = new ExpandoObject();
model = catData.ToList();

return View("Categories", model);

And then access dynamic object in view like this:然后在视图中访问动态 object,如下所示:

@model dynamic;

@foreach (var i in Model)
{
   <img src="@i.Path">
       <p>@i.Name</p>
}

However this throws an error that Model object doesn't contain Path or Name.但是,这会引发错误,即 Model object 不包含路径或名称。

Is there any other way to solve this?有没有其他方法可以解决这个问题?

The best way is create a new CatData and ViewModel classes最好的方法是创建一个新的 CatData 和 ViewModel 类

public class CatData
{
public int Id {get; set;}
public string Name {get; set;}
public string Path {get; set;}
}

public class CatDataViewModel
{
  public IEnumerable<CatData> CatDataList {get; set;}
}

fix your query修复您的查询

var catData = ( from ...
              select new CatData { Id= c.Id, Name =c.Name, Path= gg.Path }
              ).ToList();

var model= new CatDataViewModel { CatDataList=catData };

and view并查看

@model CatDataViewModel;

@foreach (var i in Model.CatDataList)
{
   <img src="@i.Path">
       <p>@i.Name</p>
}

What you need is an IEnumerable<dynamic> not a dynamic .您需要的是IEnumerable<dynamic>而不是dynamic的。 dynamic works only as an object exposing properties/methods and cannot be an IEnumerable of arbitrary objects. dynamic仅用作 object 公开属性/方法,并且不能是任意对象的IEnumerable As you can see the ExpandoObject is actually an IEnumerable of key-value pairs (map between member names & member values).如您所见, ExpandoObject实际上是键值对的IEnumerable (成员名称和成员值之间的映射)。 But that's not kind of IEnumerable you want.但这不是你想要的那种IEnumerable

This code:这段代码:

dynamic model = new ExpandoObject();
model = catData.ToList();

actually will set back your model to a list of { c.Id, c.Name, gg.Path } .实际上会将您的model设置为{ c.Id, c.Name, gg.Path }的列表。 So it's not dynamic as you thought.所以它不像你想象的那样动态。

Here's how you can build an IEnumerable<dynamic> :以下是构建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;
            });

The model then is a true IEnumerable<dynamic> and it should work now. model 是一个真正的IEnumerable<dynamic> ,它现在应该可以工作了。

You can also write an extension method to convert a normal IEnumerable<T> to IEnumerable<dynamic> to use this special scenario like this:您还可以编写一个扩展方法来将普通的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;
            }
     }
}

And use it like this:并像这样使用它:

var model = catData.AsDynamic();

With that convenient method, you will not have to manually rewrite the logic every time such as for a new list of arbitrary anonymous objects (with unknown number of properties).使用这种方便的方法,您不必每次都手动重写逻辑,例如任意匿名对象的新列表(具有未知数量的属性)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM