Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MVC5 Linq到ViewModel到Razor视图代码的改进?_C#_Asp.net Mvc_Linq_Razor - Fatal编程技术网

C# MVC5 Linq到ViewModel到Razor视图代码的改进?

C# MVC5 Linq到ViewModel到Razor视图代码的改进?,c#,asp.net-mvc,linq,razor,C#,Asp.net Mvc,Linq,Razor,我想从两个EF表(菜单和菜单项)中获取数据。然后我想将结果放入ViewModel中。因此,我可以轻松地在Razor视图中遍历数据 我让它工作了。但我是.NETMVC新手,所以我想知道我的代码是否可以改进。也许可以合并查询,并缩短查询时间。我使用的是AsEnumerable(),我不确定这是否是最好的方法 我想我的尝试没问题。但我想听听你的想法。欢迎对代码改进提出任何建议。谢谢 控制器类: public ActionResult Index(int? id) {

我想从两个EF表(菜单和菜单项)中获取数据。然后我想将结果放入ViewModel中。因此,我可以轻松地在Razor视图中遍历数据

我让它工作了。但我是.NETMVC新手,所以我想知道我的代码是否可以改进。也许可以合并查询,并缩短查询时间。我使用的是AsEnumerable(),我不确定这是否是最好的方法

我想我的尝试没问题。但我想听听你的想法。欢迎对代码改进提出任何建议。谢谢

控制器类:

   public ActionResult Index(int? id)
        {
            if (id == null) return RedirectToAction("Index", new { controller = "Menu"      });

        var menu =
            (from m in _db.Menus
             join mi in _db.MenuItems on m.Id equals mi.MenuId
             where m.Id == id
             select m).First();

        var menuItems =
            (from mi in _db.MenuItems.AsEnumerable()
             join m in _db.Menus on mi.MenuId equals m.Id
             where m.Id == id
             select new MenuItem
             {
                 Id = mi.Id,
                 Name = mi.Name,
                 Href = mi.Href,
                 CssClass = mi.CssClass,
                 CssId = mi.CssId,
                 Title = mi.Title,
                 Weight = mi.Weight
             });

        var model = new MenuModelView
        {
            Id = menu.Id,
            Name = menu.Name,
            CssClass = menu.CssClass,
            CssId = menu.CssId,
            Deleted = menu.Deleted,
            MenuItems = menuItems
        };

        return View(model);
    }
ViewModel类:

using System.Collections.Generic;

namespace DesignCrew.Areas.Admin.Models
{
    public class MenuModelView
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string CssClass { get; set; }
        public string CssId { get; set; }
        public bool Deleted { get; set; }
        public IEnumerable<MenuItem> MenuItems { get; set; }
    }
}
使用System.Collections.Generic;
命名空间DesignCrew.Areas.Admin.Models
{
公共类菜单模型视图
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串CssClass{get;set;}
公共字符串CssId{get;set;}
公共bool已删除{get;set;}
公共IEnumerable菜单项{get;set;}
}
}
Razor视图:

@model DesignCrew.Areas.Admin.Models.MenuModelView

@{
    ViewBag.Title = "Index";
}

<h2>Menu - @Html.DisplayFor(model => model.Name, new { @class = "control-label col-md-2" })</h2>

<p>
    @Html.ActionLink("Create New Item", "Create")
</p>

<table class="table">
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.MenuItems.First().Id)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.MenuItems.First().Name)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.MenuItems.First().Href)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.MenuItems.First().Title)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.MenuItems.First().CssClass)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.MenuItems.First().CssId)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.MenuItems.First().ParentId)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.MenuItems.First().Weight)
        </th>
        <th>Options</th>
    </tr>

    @foreach (var item in Model.MenuItems)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Name)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Href)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Title)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.CssClass)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.CssId)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.ParentId)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Weight)
            </td>
            <td>
                @Html.ActionLink("Edit", "Edit", new { id = item.Id }, new { @class = "link-menu" }) |
                @Html.ActionLink("Delete", "Delete", new { id = item.Id }, new { @class = "link-menu" })
            </td>
        </tr>
    }
</table>
@model DesignCrew.Areas.Admin.Models.MenuModelView
@{
ViewBag.Title=“Index”;
}
菜单-@Html.DisplayFor(model=>model.Name,新的{@class=“控制标签col-md-2”})

@ActionLink(“创建新项目”、“创建”)

@DisplayNameFor(model=>model.MenuItems.First().Id) @DisplayNameFor(model=>model.MenuItems.First().Name) @Html.DisplayNameFor(model=>model.MenuItems.First().Href) @DisplayNameFor(model=>model.MenuItems.First().Title) @DisplayNameFor(model=>model.MenuItems.First().CssClass) @DisplayNameFor(model=>model.MenuItems.First().CssId) @DisplayNameFor(model=>model.MenuItems.First().ParentId) @DisplayNameFor(model=>model.MenuItems.First().Weight) 选择权 @foreach(Model.MenuItems中的var项) { @DisplayFor(modelItem=>item.Name) @DisplayFor(modelItem=>item.Name) @Html.DisplayFor(modelItem=>item.Href) @DisplayFor(modeleItem=>item.Title) @DisplayFor(modelItem=>item.CssClass) @DisplayFor(modelItem=>item.CssId) @DisplayFor(modelItem=>item.ParentId) @DisplayFor(modelItem=>item.Weight) @ActionLink(“编辑”,“编辑”,新建{id=item.id},新建{@class=“link menu”})| @ActionLink(“删除”,“删除”,新建{id=item.id},新建{@class=“link menu”}) }
如果您的EF模型在
菜单
菜单项
之间有一个可导航外键,则不需要显式连接两个表,您可以在获取父菜单的同时立即加载子菜单项,只需从父菜单导航到子菜单:

var menu = _db.Menus
              .Include("MenuItems") // Or, use the typed version on newer EF's
              .First(m => m.id == id); // Many LINQ expressions allow predicates

return new MenuModelView
 {
    Menu = menu.Name,
    CssClass = menu.CssClass,
    CssId = menu.CssId,
    Deleted = menu.Deleted,
    MenuItems = menu.MenuItems
 }
而且,由于
MenuModelView
菜单
EF实体之间似乎有很多共同点,因此可以使用
AutoMapper
。配置后,这将允许您使用以下内容替换手动映射步骤:

return Mapper.Map<Menu, MenuModelView>(menu);

您的razor
@Model
菜单模型视图

鉴于您似乎在视图模型中重复使用EF实体,您不需要显式地
新建
映射
选择新建菜单项{}…
)将实体克隆到
视图模型
-只需使用EF引用的实体即可。此外,即使您有类似的专用
ViewModels
,像
AutoMapper
这样的工具也可以减轻手动映射的痛苦。此外,您可能不需要提供一些示例?不确定这是否有帮助,但我回答了类似的菜单相关问题。这是谢谢,这对我很有用。这样就不需要ViewModel类:var model=\u db.Menus.Include(“MenuItems”).First(m=>m.MenuId==id);返回视图(模型);不,保留viewmodel。您可能需要为视图添加额外的表示层特定物品。在这里的例子中,您的EF模型似乎对一系列UI字段进行了建模,因此表示层/域/数据层之间的区别并不十分清楚。您能给我一个简单的示例,说明MenuModelView类中表示层特定的特性吗?同样,我是.NETMVC的新手:o)我添加了一个混合
ViewModel
示例
public class MenuModelView
{
   // Presentation tier stuff
   public string PageTitle { get; set; }
   public string MetaTagsForSEO { get; set; }
   public bool IsThisARegisteredUserSoSkipTheAdverts { get; set; }

   // Your EF / Domain Model
   public Menu Menu { get; set; }
}