简体   繁体   English

当使用实体框架作为数据访问层时,如何实现业务逻辑层?

[英]How do you implement a business logic layer when using entity framework as data access layer?

Say i have 3 layers 说我有3层

layer 1: WPF Project (contains: xaml, viewmodels, mvvm framework) 第1层:WPF项目(包含:xaml,viewmodels,mvvm框架)

layer 2: business logic layer (contains: plain c# classes) 第2层:业务逻辑层(包含:普通c#类)

layer 3: entity framework (contains: repository/data access classes) 第3层:实体框架(包含:存储库/数据访问类)

when you dont want to expose your DAL(layer 3) to View(layer 1) how do you implement the business logic layer well? 当你不想将你的DAL(第3层)暴露给View(第1层)时,你如何很好地实现业务逻辑层? im having a hard time putting values back and forth the BLL objects and DAL entities. 我很难在BLL对象和DAL实体之间来回放置值。

can you please help? 你能帮忙吗?

Entity Framework doesn't work really well in a "disconnected" model. 实体框架在“断开连接”模型中不能很好地工作。 Unless something has changed, I've never been able to get it to work great easily. 除非有些事情发生了变化,否则我从未能够轻松地让它变得更好。

You could use AutoMapper in Layer 2 to create ViewModels to present to Layer 1, but then you'd still have to send the changes back to Layer 3, which could be a pain. 您可以在第2层中使用AutoMapper来创建ViewModel以呈现给第1层,但是您仍然必须将更改发送回第3层,这可能很痛苦。

If you're only developing a small app that will not change in the foreseeable, then just do whatever is quickest now. 如果你只是开发一个在可预见的情况下不会改变的小应用程序,那么现在就做任何最快的事情。 If you want a long-term maintainable app, then let me put forth the following. 如果您想要一个长期可维护的应用程序,那么让我提出以下建议。

The problem with this vertical layer approach is that whenever you need something in the view, you will have to add it to both the Business Layer (even if the business layer doesn't care about it), and the Data Layer. 这种垂直层方法的问题在于,只要您在视图中需要某些内容,就必须将其添加到业务层(即使业务层不关心它)和数据层。 This requires your business layer to look like 1) UI views of the data 2) business views of the data and 3) the database representation of the data. 这要求您的业务层看起来像1)数据的UI视图2)数据的业务视图和3)数据的数据库表示。 That and/or you need a lot of mapping in-between layers. 那和/或你需要在层之间进行大量的映射。 All of which dilutes business layer's actual purpose of representing business logic. 所有这些都淡化了业务层表示业务逻辑的实际目的。 What tends to happen then is that all the business logic gets migrated into transaction methods (that could just as well be static methods) to just change states on data objects. 接下来发生的事情是,所有业务逻辑都迁移到事务方法(也可能是静态方法),只是改变数据对象的状态。 There's nothing at all wrong with that if your problem domain is nothing but CRUD with no complex logic. 如果您的问题域只是CRUD而没有复杂的逻辑,那就没有什么不妥了。 With complex logic, such business methods can get pretty tricky or even have undefined outcomes (because complex interdependencies on "fields" can be contradictory and hard to resolve). 使用复杂的逻辑,这样的业务方法可能变得相当棘手甚至具有未定义的结果(因为“字段”的复杂相互依赖性可能是矛盾的并且难以解决)。

Assuming you have complex logic, user views of data and business representations of data are often very different, and so UI views end up with specialized models of the data. 假设您具有复杂的逻辑,数据的用户视图和数据的业务表示通常是非常不同的,因此UI视图最终会有专门的数据模型。 If I were you, I just embrace this and use a simple version of the CQRS principle. 如果我是你,我只是接受这个并使用简单版本的CQRS原则。 That is, have the data for your UI views come from a different place than where your business operations are executed. 也就是说,UI视图的数据来自与执行业务操作的位置不同的位置。 In your case, I might have an EF Model in your DAL that only services your UI views, and gives them exactly what they need (whether by database views, stored procedures, or pre-compiled report tables). 在您的情况下,我可能在您的DAL中有一个EF模型,它只为您的UI视图提供服务,并为他们提供他们所需的内容(无论是数据库视图,存储过程还是预编译的报表)。 Then create a separate EF model that services only the needs for your Business entities. 然后创建一个单独的EF模型,仅为您的业务实体提供服务。 Then when you are ready to perform an actual business action, the UI's viewmodel action method can load the business object from the business EF model (or better yet, call an object factory from the business layer which does this) and run an appropriate action on the business object. 然后,当您准备执行实际的业务操作时,UI的viewmodel操作方法可以从业务EF模型加载业务对象(或者更好的是,从执行此操作的业务层调用对象工厂)并对其执行适当的操作业务对象。 Note that I'm also making the assumption here that your database is highly relational (mostly 2nd and 3rd normal form) and you are set on using EF. 请注意,我在这里也假设您的数据库是高度关系的(主要是第二和第三范式)并且您已经开始使用EF。

I would not try to make your View Models into business logic. 我不会尝试将您的View Models变为业务逻辑。 This makes your business logic not easily reusable on other platforms or applications (like web). 这使您的业务逻辑不容易在其他平台或应用程序(如Web)上重用。 MVVM should only service the UI. MVVM应该只为UI提供服务。 In my mind, the V (view) represents what the user sees and operates. 在我看来,V(视图)代表用户看到和操作的内容。 The M (model) represents what the user chose on that view . M(模型)表示用户在该视图上选择的内容 And the VM (view model) translates between the two. VM(视图模型)在两者之间进行转换。 Your program should then take the user's validated choices (UI model) and extract the needed data out of it to perform an appropriate business operation. 然后,您的程序应该采用用户的验证选项(UI模型)并从中提取所需的数据以执行适当的业务操作。

Instead of exposing all of your DAL to View Layer, just exchange your domain objects (EF objects) between all layers. 不要将所有DAL暴露给视图层,只需在所有层之间交换域对象(EF对象)。 The structure may be similar to the following: 结构可能类似于以下内容:

  1. Presentation Layer-------- ^ 表示层-------- ^
  2. BLL --------------------------- | BLL --------------------------- | Data objects 数据对象
  3. DAL (Repositories etc.)--- | DAL(存储库等)--- |

So, all of your layers will be disconnected; 因此,您的所有图层都将断开连接; but they will share the same domain objects. 但他们将共享相同的域对象。 In real world, you can implement a similar structure by creating a seperate dll for Entity Framework entities which is shared by all layers. 在现实世界中,您可以通过为所有层共享的Entity Framework实体创建单独的dll来实现类似的结构。 Note that ObjectContext shall be only visible to DAL (by default, entities and object context are generated in the same dll, you need to seperate this into two dlls). 请注意,ObjectContext只对DAL可见(默认情况下,实体和对象上下文是在同一个dll中生成的,您需要将其分成两个dll)。

Your ViewModels are your application in MVVM, so they should be handling things like data access through your Repository classes, or business logic (either directly, or indirectly using your validation classes). 您的ViewModels 您在MVVM 的应用程序,因此它们应该通过您的Repository类或业务逻辑(直接或间接使用您的验证类)处理数据访问等事务。

If you don't want to directly reference the classes, use an Interface but be aware that you'll need to have some way of passing your inherited class to your ViewModel. 如果您不想直接引用类,请使用Interface但请注意,您需要有一些方法将继承的类传递给ViewModel。 I once did a project where we had a library of shared interfaces, such IRepository interfaces, and everything was imported/exported using MEF so the layers didn't reference each other directly. 我曾经做过一个项目,我们有一个共享接口库,比如IRepository接口,所有东西都是使用MEF导入/导出的,所以这些层没有直接相互引用。

The final (simplified) layout was: 最终(简化)布局是:

  • Models -> Contained plain data objects that could do simple validation on their own data (length, min/max values, etc) but that didn't do any advanced validation or business logic. 模型 - >包含普通数据对象,可以对自己的数据(长度,最小值/最大值等)进行简单验证,但不进行任何高级验证或业务逻辑。 Did not reference any other library. 没有引用任何其他库。

  • Common -> Contained interfaces, utilities, and other commonly shared classes. Common - >包含的接口,实用程序和其他常用的共享类。 Referenced the Model library only. 仅引用了Model库。

  • DAL -> Contained Data Access and Repositories based on repository interfaces found in Common library. DAL - >包含基于Common库中的存储库接口的数据访问和存储库。 Referenced Common library for interface definitions and utilities, and Model library because it contained the data models used or returned in data access calls 引用了用于接口定义和实用程序的公共库,以及模型库,因为它包含在数据访问调用中使用或返回的数据模型

  • ViewModels -> Contained application and business logic. ViewModels - >包含应用程序和业务逻辑。 Referenced Common for its utilities and interfaces, and Models for the data models 引用公用事业和接口的通用,以及数据模型的模型

  • Client -> Contained Views. 客户端 - >包含视图。 Referenced Models and ViewModels so it could write DataTemplates for both object types 引用模型和ViewModel,因此它可以为两种对象类型编写DataTemplates

In addition to the answer by Daryal, you can define your business-objects in your BL to be POCO's, and use EF in your DAL layer to read them from or persist them to the database. 除了Daryal的答案之外,您可以将BL中的业务对象定义为POCO,并在DAL层中使用EF从中读取它们或将它们保存到数据库中。

If you define an repository-like interface in your BL (or unit-of-work, whatever naming you give it), and implement the interface in your DAL, then all you need is a little DI to get an instance of the repository-class without having to reference the DAL all the time. 如果您在BL中定义类似于存储库的接口(或工作单元,无论您给出的命名),并在DAL中实现接口,那么您只需要一点DI来获取存储库的实例 - 类,无需一直引用DAL。 It works like a charm for me. 它对我来说就像一个魅力。

See here and here for more information. 有关更多信息,请参见此处此处

Entity framework is suppouse to be used as "Logic Layer" by itself. 实体框架本身可以用作“逻辑层”。

Your idea may have some sense, to use combine technologies. 您的想法可能有一定意义,使用组合技术。

Howevere, I think some of those Micros. Howevere,我想其中一些微观。 libraries, where designed to be used separately, unless, otherwise explicitly combined & mentioned in their websites. 图书馆,设计为单独使用,除非在其网站中另有明确组合和提及。

Good Luck. 祝好运。

I second daryal and I have implemented this in some projects. 我是第二个daryal,我已经在一些项目中实现了这一点。 It is absolutely OK to use POCO as business objects. 将POCO用作业务对象是绝对可以的。

Another approach instead of creating 2 projects (one for DB Context and one for Entities) is to use one DAL/DATA project only and reference it in BLL. 另一种方法而不是创建2个项目(一个用于DB Context,一个用于实体)是仅使用一个DAL / DATA项目并在BLL中引用它。 Then inherit the POCO class in BLL and use that class in UI layer. 然后在BLL中继承POCO类并在UI层中使用该类。 Below is the basic sample code: 以下是基本示例代码:

// assume this is EF generated POCO
namespace Owner.Project.Data{
    public partial class Product
    {
        public int ProductId { get; set; }
        public string ProductName { get; set; }
    }
}

// this is manually created class in BLL
using Owner.Project.Data;
namespace Owner.Product.Business{
    public class StoreProduct : Product {
        public bool Add (string productName){
            // TODO - add product using EF as you normally do
        }
    }
}

Now you can reference the BLL in your UI project and use StoreProduct class there. 现在,您可以在UI项目中引用BLL并在那里使用StoreProduct类。 To achieve loosely coupled pattern, Of course you could also inherit the StoreProduct class from an IStoreProduct interface and make use of it in UI or web service but that is another topic. 要实现松散耦合模式,当然您也可以从IStoreProduct接口继承StoreProduct类,并在UI或Web服务中使用它,但这是另一个主题。

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

相关问题 使用实体框架时,业务逻辑层中的数据对象 - Data Objects in Business Logic Layer when using Entity Framework 使用实体框架时如何创建 BLL(业务逻辑层)? - How to create BLL (Business logic Layer) when using Entity Framework? 在单独的数据访问和业务逻辑层中,我可以在业务层中使用Entity框架类吗? - In separate data access & business logic layer, can I use Entity framework classes in business layer? 如何在业务层和/或数据层中使用实体框架? - How to use entity framework in business layer and/or data layer? 在业务逻辑层中使用Entity Framework生成的类 - Using Entity Framework generated classes in Business Logic Layer 如何使用实体框架实现业务逻辑? - How to implement business logic using Entity Framework? 将数据访问逻辑从业务层移到数据访问层 - Move Data Access logic from the business layer to the data access layer 如何从业务层使用实体框架更新实体? - How to update an entity using Entity Framework from Business Layer? 业务逻辑层应该访问数据库/数据访问层吗? - Should Business Logic Layer access the DB/Data Access Layer? 有关项目中的业务逻辑层和数据访问层的问题 - Questions about business logic layer and data access layer in a project
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM