繁体   English   中英

EF6:在哪里创建存储过程?

[英]EF6: where to create stored procedures?

我正在使用Entity Framework 6 Code First。 要使用我的数据库,我需要一个存储过程。 每当创建数据库时,都需要创建此存储过程。

编辑:存储过程的原因写在这篇文章的结尾。

从Stackoverflow我知道如何创建存储过程以及如何调用它。 我的问题是在哪里创建它?

我的第一个直觉是在DbContext.OnModelCreating中 每当创建模型时,都会调用此函数。 在此功能中,您将告诉模型构建者模型应该是什么样。

,在此功能中,我还不能使用DbContext。 有一些功能可以覆盖“插入/更新/删除”过程,但是我需要一个不同的过程。

我考虑在DropCreateDataBaseIfModelChanges的Seed函数中添加该函数,但这将禁止我的DbContext用户使用其所需的数据为数据库播种。

DbMigrations似乎是为了将现有数据库迁移到新数据库而开发的。 创建数据库的第一个版本时不使用。

那么在哪里创建存储过程呢?


编辑。 我需要存储过程的原因如下

我的服务收到有关客户今天花钱购物的通知。 我需要记住每个客户的当天总计。

  • 如果客户在date上还没有花费任何东西, 也就是说 ,如果不存在带有(customerId,date)的记录,则插入一条带有花费值的记录
  • 如果客户已经在datae上花了一些也就是说 ,如果已经存在带有(customerId,date)的记录,则将花费的值添加到记录中的值

像这样:

public void InsertOrAdd(int customerId, DateTime date, decimal value)
{
    using (var dbContext = CreateContext())
    {
        var retrievedRecord = dbContext.Find(...)
        if (retrievedRecord == null)
        {
            InsertRecord(customerId, date, value);
        }
        else
        {
            retrievedRecord.Value += value;
            dbContext.SaveChanges();
        }
    }
}

问题是在“查找”之后,其他人可能已经插入了一条记录。 在那种情况下,我应该添加值。 而是会有两个记录。 或者在我处理现有记录并添加值时,其他人可能会处理相同的现有记录。 因此,值的添加应在数据库内部使用如下语句完成:

update [CustomerSpends]
Set [SpentValue] = [SpentValue] + @Value
Where [CustomerId] = @CustomerId and [SpentDate] = @SpentDate

第二次编辑正如Ivan Yuriev *已经提到的,可以使用事务来解决上述问题。 但是我仍然会遇到增加支出的问题。

如果这是一个三步骤的过程(如Ivan所建议的那样),则它将是:

  • 获取现有记录
  • 将支出值添加到记录的总值中
  • 保存更改

这样做的缺点是我总是需要两次往返数据库。 此外,我得到了一系列的客户支出。 如果其中任何一个处理失败,则需要回滚所有内容。 即使使用交易,也可能存在竞争条件

最高的事务隔离级别(MSDN)已读取为已提交。

READ COMMITTED指定语句不能读取已被其他事务修改但未提交的数据。 这样可以防止脏读。 数据可以被当前事务中各个语句之间的其他事务更改,从而导致不可重复的读取或幻像数据。

当使用上面定义的三步过程时,我获取记录X,总花费值为5.00美元。 当我将总计增加3美元时,其他人也可以获取记录X,因为它尚未被修改。 另一个接收的记录总计为$5。添加后,总值为$8。我使用SaveChanges更新值,并继续其他记录。 一段时间后,我提交更改。 另一个仍有$ 5记录的进程应加$ 2,以$ 7结尾,而最终结果应为$ 10

使用事务不能阻止其他人读取数据。 因此,获取-添加值-更新应在一条SQL语句中完成

通过创建空白迁移并在Up方法中添加存储过程并在Down Method中删除该存储过程的最佳管理方式

这将像。

1)通过在Package Manger Console上运行命令来添加空白迁移

add-migration 'SomeName' -IgnoreChanges

它将创建迁移文件

2)现在,在“向上”中添加存储过程,在“向下”中删除存储过程

public partial class SomeName: DbMigration
    {
        public override void Up()
        {
            Sql(@"Add Command For StoredProcedure");

        }

        public override void Down()
        {
            Sql(@"Drop Command for Stored Procedure")
        }
    } 

添加Drop in Down方法同样重要。

无处。 我发现代码优先迁移非常有限,只有只有对SQL Server概念和功能缺乏深入了解的人才能使用它。

我走的路是:

  • 我维护一个主数据库并将架构同步到架构项目。
  • 定期生成增量脚本,然后由我手动维护。
  • 我有一个库,该库根据扩展属性中存储的数据库的版本号,根据需要应用增量脚本。

不使用迁移的原因很简单-无论如何,您最终不得不提交太多的SQL脚本。 迁移甚至无法处理琐碎的情况,例如正确的完全配置的索引(过滤的索引),不了解存储过程,触发器和视图,无法处理分区表,无法有效地处理可能需要临时表的数据迁移在表布局更改时存储数据。 因为我不处理琐碎的数据库,所以几乎每天都需要几乎所有这些功能。

说出全部真相-我从来没有找到过代码甚至是一种有效的方法。 太容易出错了。 更糟糕的是,db首先使用EF工具-主要是因为edmx设计器变得越来越烂,完全无法处理更新。 但是可以使用第三方编辑器,并且它们可以工作。

暂无
暂无

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

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