在n层实体框架中使用存储过程

本文关键字:存储过程 框架 实体 | 更新日期: 2023-09-27 18:06:33

在尝试利用n层实体框架中的存储过程时,我遇到了一些有趣的情况。我想确认这些情况是不是我们的实现所独有的,并且想知道我们的解决方案是否是最好的,或者是否有更好的解决方案。

  1. 映射要求:当对已映射的存储过程使用context.SaveChanges()时,所有存储过程必须映射到给定的实体;也就是说,如果插入SP被映射,而更新SP没有被映射,那么在尝试处理更新时就会出现异常,因为框架"无法在映射文件中找到EntityType 'PriceFileCustomerPrice'的UpdateFunctionMapping"。我们希望只映射那些必要的sp,并让框架处理插入/更新/删除处理的其余部分。如何映射Insert操作而不映射Update或Delete操作?

  2. CHANGESET中的丢失数据:在尝试使用映射更新存储过程时存在一个问题,因为框架只提供已经更改的属性的数据,而所有其他属性(除了键)由于CHANGESET忽略了所有未更改的记录和属性而具有空值或零值。因此,不会传递未更改的实体属性的值,但是映射的存储过程需要大多数属性/sp参数的值;这会导致更新错误地将有效数据替换为null或零。(如果不使用存储过程进行更新,则不会出现此问题;也就是说,框架成功地使用了自己的更新方法来处理丢失的数据。

    。我们的解决方案是从OnChange()调用存储过程,而不是映射它,但是…调用OnChange()方法后,框架仍然调用自己的Update方法,然后抛出一个异常(在插入)由于键违反;因此,为了防止这种异常,我们映射了不执行任何操作的mock/dummy存储过程。

    b。是否有一种方法来映射更新存储过程并接收所有更改和未更改的属性值?

  3. 分离ENTITYSETS:调用SaveChanges()将处理所有ENTITYSETS的任何和所有修改;因此,如果一个EntitySet已经被修改,但不应该被保存,它必须在调用SaveChanges()之前被分离(Context.EntitySet.DetachAll()),然后每次重新连接一个(Context.Attach(entity))。类似地,单个实体也可以分离和重新连接。这是处理这种情况的最好方法吗?(我相信这只是一个通用的EF问题,不是特定于N-Tier的)

@ChristofSenn我将感谢您的回复。谢谢你!

在n层实体框架中使用存储过程

  1. 映射要求:据我所知,如果映射任何创建、更新或删除函数,EF不会回落到默认行为。因此,除非你知道一个给定的实体,例如你从不删除记录,否则如果你映射了插入或更新,你就需要映射delete函数。在决定是否使用存储进程时,我发现这篇文章很有用。

  2. CHANGESET中丢失的数据:正如你已经发现的那样,默认情况下N-Tier实体框架只传输从客户端到服务器的更改(或其他所需的数据,如PKs)。应该始终包含的属性可以根据需要使用IncludeOnUpdateAttributeIncludeOnDeleteAttribute进行注释。

  3. 选择性地保存更改:上下文。SaveChanges将给定上下文的所有挂起的更改作为一个工作单元提交给数据服务。如果你只想保存特定的实体,你可以从上下文中删除(->分离)其他实体,或者添加(->附加)要保存的实体到上下文的一个单独的实例中,你可以临时创建这个上下文,只是为了这个目的。没有什么可以阻止您将一个实体同时附加到多个上下文。但是,应该谨慎使用,因为它很容易出错,特别是在涉及具有关系的实体时。