Linq to sql ASP.NET MVC-多层结构
我一直在使用LinqToSql进行ASP.NETMVC项目。该应用程序有3层:UI、业务和数据 在过去的几天里,我实现了(我现在仍然是)一个Excel文件上传。因此,我的控制器接收上传的文件,做一些事情,将信息传递给企业,然后传递给数据。但是,随着这一趋势的发展,出现了一些疑问 以下是我的一些疑问(我认为子弹是最简单的表达方式):Linq to sql ASP.NET MVC-多层结构,linq-to-sql,asp.net-mvc-2,business-logic,multi-layer,Linq To Sql,Asp.net Mvc 2,Business Logic,Multi Layer,我一直在使用LinqToSql进行ASP.NETMVC项目。该应用程序有3层:UI、业务和数据 在过去的几天里,我实现了(我现在仍然是)一个Excel文件上传。因此,我的控制器接收上传的文件,做一些事情,将信息传递给企业,然后传递给数据。但是,随着这一趋势的发展,出现了一些疑问 以下是我的一些疑问(我认为子弹是最简单的表达方式): 必须验证Excel文件。应用程序必须验证工作表值是否正确,如果正确,则插入/更新数据库。我应该在Controller中还是在业务中验证Excel 此Excel可能会将
新产品()代码>在UI层中创建新实例时有问题吗?还是在业务中创建新实例更好?将一个对象从UI传递到业务是更好的选择,还是传递所有类属性并在业务中创建该对象更好
提前谢谢 你确实应该避免使用脂肪控制器。但总是说起来容易做起来难 让我试着用一个例子来回答你们的问题。与往常一样,您可以从设计一个视图模型开始,该模型将表示用户发送到此操作的数据(不要使用任何弱类型的
FormCollection
或ViewData
)
然后我们转到控制器:
public ProductsController: Controller
{
private readonly IProductsService _service;
public ProductsController(IProductsService service)
{
_service = service;
}
public ActionResult Upload()
{
var model = new UploadViewModel();
return View(model);
}
[HttpPost]
public ActionResult Upload(UploadViewModel model)
{
if (!ModelState.IsValid)
{
// The model was not valid => redisplay the form
// so that the user can fix his errors
return View(model);
}
// at this stage we know that the model passed UI validation
// so let's hand it to the service layer by constructing a
// business model
string error;
if (!_service.TryProcessFile(model.File.InputStream, out error))
{
// there was an error while processing the file =>
// redisplay the view and inform the user
ModelState.AddModelError("file", error);
return View(model);
}
return Content("thanks for submitting", "text/plain");
}
}
最后一位是服务层。它将有两个依赖项:第一个将负责解析输入流并返回产品的列表,第二个将负责将这些产品持久化到数据库
就这样,
public class ProductsService: IProductsService
{
private readonly IProductsParser _productsParser;
private readonly IProductsRepository _productsRepository;
public ProductsService(IProductsParser productsParser, IProductsRepository productsRepository)
{
_productsParser = productsParser;
_productsRepository = productsRepository;
}
public bool TryProcessFile(Stream input, out string error)
{
error = "";
try
{
// Parse the Excel file to extract products
IEnumerable<Product> products = _productsParser.Parse(input);
// TODO: Here you may validate whether the products that were
// extracted from the Excel file correspond to your business
// requirements and return false if not
// At this stage we have validated the products => let's persist them
_productsRepository.Save(products);
return true;
}
catch (Exception ex)
{
error = ex.Message;
}
return false;
}
}
公共类产品服务:IPProductsService
{
私有只读IPProductsParser\u productsParser;
私有只读IPProductsRepository\u productsRepository;
公共产品服务(IPProductsParser产品sParser、IPProductsRepository产品Repository)
{
_productsParser=productsParser;
_productsRepository=productsRepository;
}
公共bool进程文件(流输入,输出字符串错误)
{
错误=”;
尝试
{
//解析Excel文件以提取产品
IEnumerable products=\u productsParser.Parse(输入);
//TODO:在这里,您可以验证
//从Excel文件中提取,与您的业务相对应
//要求,否则返回false
//在这个阶段,我们已经验证了产品=>让我们将其持久化
_产品存储。保存(产品);
返回true;
}
捕获(例外情况除外)
{
错误=例如消息;
}
返回false;
}
}
当然,这些依赖关系有两种实现:
public class ExcelProductsParser: IProductsParser
{
public IEnumerable<Product> Parse(Stream input)
{
// parse the Excel file and return a list of products
// that you might have extracted from it
...
}
}
公共类ExcelProductSpaser:IPProductSpaser
{
公共IEnumerable解析(流输入)
{
//解析Excel文件并返回产品列表
//你可能从中提取的
...
}
}
以及存储库:
public class Linq2SqlProductsRepository: IProductsRepository
{
public void Save(IEnumerable<Product> products)
{
// save the products to the database
...
}
}
公共类Linq2SqlProductsRepository:IProductsRepository
{
公共作废保存(IEnumerable产品)
{
//将产品保存到数据库中
...
}
}
备注:您可以使用其他属性丰富视图模型,这些属性将表示一些元数据,我们可以将这些元数据与此文件上载关联,并且表单上可能有一些相应的输入字段。然后您可以定义一个要传递给TryProcessFile
方法的业务模型,而不是一个简单的流
。在这种情况下,可以在控制器操作中使用来映射UploadViewModel
和您将定义的新业务模型。Darin,谢谢您的评论!它帮助我建立了一些关于重构代码的坚实思想!
public class Linq2SqlProductsRepository: IProductsRepository
{
public void Save(IEnumerable<Product> products)
{
// save the products to the database
...
}
}