简体   繁体   English

向ASP> NET MVC 3 C#中的存储库添加简单的业务逻辑

[英]Add simple business logic to repository in ASP>NET MVC 3 C#

I have a question concerning an issue that has already been disputed many times in stackoverflow (I apologize for this) but no general answer has ever been given because of the subjectivity of the topic from one case to another: can we add business logic to the repository layer according to the repository pattern? 我有一个问题,这个问题在stackoverflow中已经引起了很多争议(对此我表示歉意),但是由于该主题从一种情况到另一种情况的主观性,因此没有给出任何一般性的答案:我们可以在其中添加业务逻辑吗?根据存储库模式存储库层? I have an MVC 3 application with ViewModels (that means I don't use the ViewData at all). 我有一个带有ViewModels的MVC 3应用程序(这意味着我根本不使用ViewData)。 The model is an LinqtoSQL EF of course connected to a database. 该模型是当然连接到数据库的LinqtoSQL EF。 Currently I am accessing the entities directly from the controllers which contain all the business logic and I wrap the data needed for the Views in specific ViewModels. 目前,我正在直接从包含所有业务逻辑的控制器中访问实体,并将视图所需的数据包装在特定的ViewModels中。 Now I am starting to refactor and I realized that the best way to avoid code duplication, besides optimizing the ViewModels, is to delegate all the queries to a repository, which communicates with the EF, and create tailored methods to be used by the controller. 现在,我开始进行重构,我意识到避免代码重复的最佳方法,除了优化ViewModels之外,还有将所有查询委托给与EF通信的存储库,并创建供控制器使用的定制方法。 Now, taking into account that I would like the repository to return actual objects and not expressions, I was thinking about delegating small pieces of business logic to the repository in order to make my code clearer. 现在,考虑到我希望存储库返回实际的对象而不是表达式,我正在考虑将一小部分业务逻辑委派给存储库,以使代码更清晰。 However for the sake of loose coupling, I would like to have your opinion. 但是,为了松散耦合,我想请您发表意见。 In the code shown below (which currently resides in the controller) all the variables except lprojectionPercactualValue are taken from the database. 在下面显示的代码(当前位于控制器中)中,除lprojectionPercactualValue之外的所有变量均从数据库中获取。 Therefore I wanted to move this piece of code to the repository and call a method with signature: 因此,我想将这段代码移至存储库并调用带有签名的方法:

public string getColor (int ItemId, float lprojectionPercactualValue);

The method needs the ItemId in order to retrieve the values specific for that Item. 该方法需要ItemId以便检索特定于该Item的值。 What do you think about this design decision? 您如何看待这个设计决定? Is it better to leave the code in the controller, move to another method still in the controller (create a method or even a class dedicated) or move it to the repository as explained? 最好将代码留在控制器中,移至仍在控制器中的另一个方法(创建方法,甚至是专用的类),或者按说明将其移至存储库中?

if (litem.Ascending == true)
{
    if (lprojectionPercactualValue < lminThreshold)
    {
        lcolor = "RED";
    }
    else if (lprojectionPercactualValue > lminThreshold && lprojectionPercactualValue < lmedThreshold)
    {                                   
        lcolor = "YELLOW";
    }
    else //(percValue >= item.Max_Threshold)
    {
        lcolor = "GREEN";
    }
}

else
{
    if (lprojectionPercactualValue > lminThreshold)
    {
        lcolor = "RED";
    }
    else if (lprojectionPercactualValue < lminThreshold && lprojectionPercactualValue > lmedThreshold)
    {
        lcolor = "YELLOW";
    }
    else //(percValue <= item.Max_Threshold)
    {
        lcolor = "GREEN";
    }
}

It is not recommended. 不推荐。

How does Repository now about the lminThreshold ? 现在,Repository如何处理lminThreshold What if this value itself needs to come from a lookup table or a config file? 如果此值本身需要来自查找表或配置文件怎么办?

Move it to business layer - and if you do not have one, to the controller. 将其移至业务层-如果没有,则移至控制器。

Wrap your EF logic inside a DAL layer that you proxy via a Repository class. 将您的EF逻辑包装在通过存储库类代理的DAL层中。 This is raw data and since you require additional crunching on it, it is recommanded to have a service layer that uses it and applies your custom business rules over it. 这是原始数据,由于您需要对其进行其他处理,因此建议使用它使用服务层并在其上应用自定义业务规则。 The Repository here is meant to discourage any DB code duplication. 这里的存储库旨在阻止任何DB代码重复。

At this point, you only check if the lprojectionPercactualValue goes over some treshold, but what if, at some point, you will need to compute that treshold in some fancy manner or you decide to perform some sort of validation or some other thing like that. 在这一点上,您仅检查lprojectionPercactualValue是否超过某个阈值,但是如果在某个时候需要以某种幻想的方式计算该阈值,或者您决定执行某种验证或类似的事情,那该怎么办? These are all domain specific decisions and they should reside in a layer of their own. 这些都是特定于领域的决策,应该驻留在它们自己的层中。

恕我直言,您最好在控制器和存储库之间添加一个业务层,并将上面的getColor代码放入业务层中(或者根据需要将其分成几种方法),如果在其他控制器中需要它,该怎么办?不再是简单的if / else,如果明天您必须从Web服务获取阈值,您想在控制器或存储库代码中进行所有这些更改吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM