我想获取一个表的模型并使用添加字段创建一个viewmodel,然后将其填充为视图。我如何在控制器中执行此操作?当它只是一个模型时它起作用但我不确定如何在它是一个视图模型时做同样的事情。我是asp.net mvc的新手,所以任何帮助都会受到赞赏。
型号:
public partial class tblTag
{
public int TagId { get; set; }
public string TagName { get; set; }
}
视图模型:
public class tblTagViewModel
{
public string TagName { get; set; }
public string TagNameClr
{
get
{
if (TagName == "Test")
{
return "green";
}
else
{
return "red";
}
}
}
}
控制器:
无法隐式转换类型' System.Data.Entity.DbSet< _1MvcSqlServer.Models.tblTag>'到' _1MvcSqlServer.ViewModel.tblTagViewModel'
既然它是一个视图模型,实体的结构是不同的,我认为这就是问题所在。我该如何解决这个问题?
private testEntities db = new testEntities();
public ActionResult Test()
{
ViewModel.tblTagViewModel model = new ViewModel.tblTagViewModel();
model = db.tblTags;
return(model);
}
以下是我最终将其付诸实践的原因。这是正确的方法吗?
public ActionResult Test()
{
List<ViewModel.tblTagViewModel> list = new List<ViewModel.tblTagViewModel>();
var model = new ViewModel.tblTagViewModel();
foreach(tblTag p in db.tblTags)
{
ViewModel.tblTagViewModel nw = new ViewModel.tblTagViewModel();
nw.TagName = p.TagName;
list.Add(nw);
}
return View(list);
}
答案 0 :(得分:0)
正确的方法 - 创建业务层,它将从数据库层获取数据并将此数据传递给View层(反之亦然,从View层获取数据并传递到DB层)。
另外,我建议看一下IoC(DI)方法:
业务层:
首先,您创建新的ClassLibrary项目并创建Business层POCO类和存储库的抽象:
/// <summary>
/// this is a Business layer class, which is very similar on EF class
/// </summary>
public class Tag
{
public int TagId { get; set; }
public string TagName { get; set; }
}
public interface IRepository
{
List<Tag> GetTagList();
}
然后创建服务:
public class Service
{
private readonly IRepository _repository;
public Service(IRepository repository)
{
if (repository == null)
throw new ArgumentNullException("repository");
_repository = repository;
}
public List<Tag> GetTagList()
{
return _repository.GetTagList();
}
}
在这个阶段你已经编译了Business层的版本。您可以添加应用程序的所有复杂逻辑并对其进行测试。 Attent,没有DB amd查看部件!
下一步 - 创建数据库图层
数据库层:
在解决方案中再创建一个类库,添加到BL项目的链接并添加如下代码:
public class EFRepository : IRepository
{
private ... _db;
public EFRepository()
{
.....
}
public List<Tag> GetTagList()
{
var tags = (from i in _db.tblTags select new Tag { TagId = i.TagId, TagName = i.TagName }).ToList();
}
}
所以,你有DB和BL层。而你的BL层不依赖于DB层,反之亦然,DB层依赖于BL层。这是一种正确的方法,你的应用程序的业务逻辑不应该依赖于DB!
最后一步 - 查看图层。
查看图层
您也可以将View Layer分隔到不同的项目。我在ASP.NET MVC应用程序中执行此操作。添加对DB和BL项目的引用
public class tblTagViewModel
{
public string TagName { get; set; }
public string TagNameClr
{
get
{
if (TagName == "Test")
{
return "green";
}
else
{
return "red";
}
}
}
}
和您的控制人员:
public class HomeController : Controller
{
private readonly Service _service;
public HomeController(IRepository repository)
{
if (repository == null)
throw new ArgumentNullException("repository");
_service = new Service(repository);
}
public ActionResult Test()
{
List<ViewModel.tblTagViewModel> list = new List<ViewModel.tblTagViewModel>();
vat taglist = _service.GetTagList();
foreach (tblTag p in taglist)
{
ViewModel.tblTagViewModel nw = new ViewModel.tblTagViewModel();
nw.TagName = p.TagName;
list.Add(nw);
}
return View(list);
}
}
,最后一步,将数据库实施设置为您的网络应用程序:
public class MyControllerFactory : DefaultControllerFactory
{
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
var efRepository = new EFRepository();
if (controllerType == typeof(HomeController))
{
return new HomeController(efRepository );
}
return base.GetControllerInstance(requestContext, controllerType);
}
注意,你的web应用程序不依赖于DB层,它只依赖于BL层(这也是合乎逻辑的)。只有一个地方可以在您的Web应用程序中设置EFRepository - 在控制器工厂中。
使用这种方法,您可以轻松地将EFRepository更改为另一个IRepository实现,具有不同的DB甚至假数据库。您可以在没有不必要关系的情况下测试应用程序的任您拥有强大而正确的架构,您的应用程序依赖于业务逻辑层而不依赖于DB层等.DB层或View层中的任何更改都不会影响逻辑层
为了映射具有许多属性的类似POCO类(即BL和DB,BL和View类),您可以使用Automapper