【问题标题】:Better way to use model class helper methods使用模型类辅助方法的更好方法
【发布时间】:2013-11-13 10:37:58
【问题描述】:

在我的模型类中,我使用了一个方法调用 IsAlreadyAssigned,如下所示:-

public partial class DataCenter 
{
     public bool IsAlreadyAssigned()
     {
         return (TMSRacks.Any() ||  TMsRouters.Any() || Zones.Any());
     }
}

这个辅助方法的主要目的是在对象有子记录时隐藏视图上的删除按钮;如下:-

<td>
    @Html.ActionLink("Edit", "Edit", new { id= item.ID}) 
    @if (!item.IsAlreadyAssigned()) 
    { 
        <text>|</text> 
        @Ajax.ActionLink("Delete",
                         "Delete", "DataCenter",
                         new { id = item.ID },
                         new AjaxOptions
                         { 
                             Confirm = "Are You sure You want to delete (" + item.Name + ")",
                             HttpMethod = "Post",
                             OnSuccess = "deletionconfirmation",
                             OnFailure = "deletionerror"
                         })

    }
</td>

但是在一次显示 10 条记录的索引视图中,我将相应地隐藏或显示删除链接,因此我必须在查询中包含所有导航属性,如下所示:-

public IQueryable<DataCenter> AllFindDataCenters(string q, bool forautocomplete = false)
{
    return from datacenter in tms.DataCenters.Where(a=> (String.IsNullOrEmpty(q)) || ( a.Name.ToUpper().StartsWith(q.ToUpper())))
        .Include(a=>a.Zones)
        .Include(a=>a.TMsRouters)
        .Include(a=>a.TMSRacks)
        select datacenter;
}

否则,我的索引视图上的每条记录最多可能对数据库进行三个查询,以检查是否有任何子记录。 所以我最终包括了上面显示的所有导航属性,只是为了实现隐藏/显示删除链接的要求。那么有没有更好的方法来管理我的逻辑,因为我不需要显示任何导航属性数据(tmsrouter、tmsfirewalls、zonea),我只想知道是否存在至少一条记录? 谢谢

【问题讨论】:

  • any 是我认为最有效的方法..
  • 但在我的情况下,我必须拉出所有导航属性,以决定 Any() 是返回 true 还是 false .. 这就是问题所在。我的问题不在于 Any(),它本身..

标签: asp.net asp.net-mvc linq entity-framework asp.net-mvc-4


【解决方案1】:

不要在视图中直接使用您的业务模型,而是返回一个 view 模型并公开您需要的信息,例如

public class DataCenterViewModel
{
    ...
    public bool HasZones { get; set; }
    public bool HasTmsRouters { get; set; }
    public bool HasTmsRacks { get; set; }

    public bool AlreadyAssigned { get { return HasZones || HasTmsRouters || HasTmsRacks; } }
}

然后在您的查询中构建您的视图模型。另外,仅供参考,在将内容传递给视图时,最好使用更通用的构造,例如 IEnumerable&lt;T&gt;IQueryable&lt;T&gt; 建议您在视图中进一步查询数据源。

public IEnumerable<DataCenterViewModel> AllFindDataCenters(string q, bool forautocomplete = false)
{
    return tms.DataCenters.Where(...)
                          .Select(x => new DataCenterViewModel
                                       {
                                           ...
                                           HasZones = x.Zones.Any(),
                                           HasTmsRouters = x.TMSRouters.Any(),
                                           HasTmsRacks = x.TMSRacks.Any()
                                       })
                          .ToList();

}

然后终于在你的视野中

<td>
@Html.ActionLink("Edit", "Edit", new { id= item.ID}) 
@if (!item.AlreadyAssigned) 
{
    ...
}
</td>

【讨论】:

  • 是的,我明白了你的意思,但不幸的是,现阶段很难对我的应用程序进行如此重大的更改。我可能会在进一步的版本中考虑你的方法。但是有没有办法以任何方式改进我的原始代码?
  • @johnG 这并不是一个真正的重大变化,您只是将DataCenter 替换为DataCenterViewModel。那你有什么样的限制?除非我知道您的限制是什么,否则我无法真正建议更改。
  • 限制是时间和资源。我的意思是我们正处于最后阶段。我做了一些调整,结果出来了。所以为我们的 15 个控制器类修改它并不容易。谢谢
  • @johnG 那么你愿意在DataCenter 类中进行更改吗?添加一些属性?
猜你喜欢
  • 2015-03-27
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 2011-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-28
相关资源
最近更新 更多