我如何保持翻译ViewModel的逻辑';s值到Where子句,以应用于My Controller之外的linq查

本文关键字:应用于 子句 My Controller linq Where ViewModel 翻译 何保持 值到 | 更新日期: 2023-09-27 18:19:56

同样的问题不断出现。我有一个没有任何持久支持的viewModel。它只是一个生成搜索输入表单的ViewModel

我想根据用户输入的值构建一个大型where子句。如果Action接受作为参数SearchViewModel,我该如何在不将viewModel传递到服务层的情况下做到这一点?服务不应该知道ViewModels,对吧?哦,如果我序列化它,那么它将是一个大字符串,键/值将是强类型的。

SearchViewModel这只是一个片段。

[Display(Name="Address")]
  public string AddressKeywords { get; set; }
        /// <summary>
        ///     Gets or sets the census.
        /// </summary>
        public string Census { get; set; }
        /// <summary>
        ///     Gets or sets the lot block sub.
        /// </summary>
        public string LotBlockSub { get; set; }
        /// <summary>
        ///     Gets or sets the owner keywords.
        /// </summary>
        [Display(Name="Owner")]
        public string OwnerKeywords { get; set; }

在我的控制器动作中,我想到了这样的事情。但我认为所有这些逻辑都不属于我的控制器。

ActionResult GetSearchResults(SearchViewModel model){
    var query = service.GetAllParcels();
    if(model.Census != null){
    query = query.Where(x=>x.Census == model.Census);
    }
    if (model.OwnerKeywords != null){
    query = query.Where(x=>x.Owners == model.OwnerKeywords);
    }
    return View(query.ToList());
    }

我如何保持翻译ViewModel的逻辑';s值到Where子句,以应用于My Controller之外的linq查

如何在不将viewModel传递到服务层的情况下完成此操作?服务不应该知道ViewModels,对吧?

没错,视图模型是表示层对象,所以将它们排除在服务层或持久层之外是个好主意。此外,控制器应该是精简的,没有太多的逻辑,所以我认为将这些代码分解到其他地方是正确的方法。以下是针对您的情况的一些替代方案:

  • 将您的价值观从控制器传递到服务层
  • 创建一个助手类,为您创建字符串
  • 将视图模型映射到另一个类/实体,并将其传递给服务层

您在这里所做的是使用LINQ来代替更严格的OO"规范模式"。如果您的应用程序分层允许(即,如果您可以从web前端直接访问数据库,而不是所有架构都这样做),那么这没什么错,尽管您可能希望将其推送到"服务"类中,而不是在控制器中执行大量查询逻辑。在分离这类事物时,您希望有多严格取决于应用程序的大小和复杂性。

引入一点抽象的一种方法是让视图模型实现一个接口(例如:ISearchSpecification),该接口定义了可以在查询谓词中使用的属性。然后,您可以创建一个在接口上操作的类或扩展方法。

public interface IMySearchSpec 
{
   string City { get; }
   string State { get; }
}
public class MyViewModel : IMySearchSpec
{
   ...implement IMySearchSpec and perhaps other things...
}
public static class QueryExtensions
{
   public static IQueryable<T> ApplyPredicate(this IQueryable<T> query, IMySearchSpec searchSpec) 
   {
        if (searchSpec.City != null )
        {
            query = query.Where( x => x.City == searchSpec.city );
        }
        // ..etc..
       return query;
   }
}
// then, in your controller
var filteredQuery = query.ApplyPredicate(viewModel);

您也可以以类似的方式应用分页/排序逻辑。

通常您不会将视图模型作为视图中的参数;视图模型从控制器传递到视图。

我的逻辑背后的理由是,如果一个大的(大量数据)视图模型从控制器传递到视图,然后从视图传递回控制器,可能会成为一个问题(性能);特别是如果您不需要控制器操作中的所有信息。我想您可以将视图创建的视图模型发送到控制器(原始较大视图模型的子集)。我对这个问题的理解是,他想在控制器->视图->控制器之间来回传递相同的视图模型。

在MVC中,什么是ViewModel

ViewModel还可以从以下数据类型执行转换:您的模型携带您的视图可以方便地工作的数据类型具有这甚至可能意味着ViewModel不包含Models直接但其他运载(可能是其子集)相同更合适格式的信息。

考虑一下您可以有一个聚集相册的库模型和DVD之间的区别ViewModel正是Model不在乎(甚至不知道关于)视图,而ViewModel具有明确的目的

将控制器操作的参数更改为类,如SearchParameters。将SearchParameters传递到服务层是可以的。