简体   繁体   English

从实体框架调用存储过程

[英]Call Stored Procedure from Entity Framework

I've done a lot of Googling re this subject, but can't seem to find any clear answer that works. 我在这个问题上做了很多谷歌搜索,但是似乎找不到有效的明确答案。 This maybe because of the way the different EF versions has worked (or not) in the past. 这可能是由于不同EF版本过去的工作方式(或无效)的缘故。

I'm currently using Asp.Net 4.0 with EF 6.1. 我目前正在使用Asp.Net 4.0和EF 6.1。 My model is database first. 我的模型是数据库优先。 Additionally, I'm using my own UOW, repository pattern but this is just for information. 另外,我正在使用自己的UOW存储库模式,但这仅供参考。

Firstly, the reason I want to call a stored procedure is because I need to incorporate a 'counter' into my table - put simply each time anyone visits a particular partner, I need to increment the counter. 首先,我要调用存储过程的原因是因为我需要在表中合并一个“计数器”-简而言之,每次有人访问特定伙伴时,我都需要增加计数器。 Of course, the main issue using EF is concurrency. 当然,使用EF的主要问题是并发性。

The articles I've read, tell me that EF isn't good at this type of update, however if this is now deemed easier to achieve in later EF versions, I'd be interested to hear more. 我读过的文章告诉我,EF在这种类型的更新上并不擅长,但是,如果现在认为在更高版本的EF中更容易实现此功能,我想听听更多。 Otherwise, I'm left with a native stored procedure - 2 options I guess 否则,我将剩下一个本地存储过程-我猜有2个选项

  1. call from EF, and 来自EF的电话,以及
  2. call directly 直接致电

Since I've been using primarily EF, my knowledge of SQL is fairly sparse, but I've created the following stored procedure: 由于我主要使用EF,因此我对SQL的了解还很少,但是我创建了以下存储过程:

ALTER PROCEDURE dbo.Popularity_Update
   @TermID smallint
AS
   SET NOCOUNT ON

   DECLARE @Now date = SYSDATETIME()

   BEGIN TRY
      MERGE Popularity AS t
      USING (SELECT @TermID AS TermID, @Now AS VisitDate) AS s ON t.TermID = s.TermID 
                                                               AND t.VisitDate = s.VisitDate

      WHEN MATCHED THEN
          UPDATE 
              SET VisitCount += 1

      WHEN NOT MATCHED BY TARGET THEN
          INSERT (TermID, VisitDate, VisitCount)
          VALUES (s.TermID, s.VisitDate, 1);

      END TRY
      BEGIN CATCH
      END CATCH

That's were I get lost. 那就是我迷路了。 I noticed within the EF designer that the stored procedure could be referenced, so I added the table to my model and then mapped the stored procedure. 我注意到在EF设计器中可以引用存储过程,因此我将表添加到了模型中,然后映射了存储过程。

在此处输入图片说明

But I also noticed that I can reference a stored procedure from code using the following code: 但是我也注意到我可以使用以下代码从代码中引用存储过程:

var name = new SqlParameter("TermID", typeof(short));
uow.Context.Database.ExecuteSqlCommand("Popularity_Update", name);

At the moment, I'm just confused and have lots of questions. 此刻,我很困惑,有很多问题。

  • Can this be done in EF without a stored procedure? 无需存储过程就能在EF中完成此操作吗?
  • Should it be done in EF without a stored procedure? 应该在没有存储过程的情况下在EF中完成吗?
  • If I use a stored procedure - whats the best way to do this? 如果我使用存储过程-最好的方法是什么?

I'd appreciate any help/guidance available. 如果有任何帮助/指导,我将不胜感激。

you cant use this in EF without a stored procedure. 您不能在没有存储过程的情况下在EF中使用它。

the best way to do this is using the dynamically mapping. 最好的方法是使用动态映射。

Heres How I usually execute my stored procedures. 这是我通常执行存储过程的方式。

internal static Database Db = DatabaseFactory.CreateDatabase();//stated in my dataaccess layer

DbCommand dbCommand = Db.GetStoredProcCommand("Yourstoreprocturename");
Db.AddInParameter(dbCommand, "TermID", DbType.Int32, parameterofTermID);
Db.ExecuteNonQuery(dbCommand);

Took on board what the previous answers offered. 接受了先前的答案。 Came up with this solution that caters specifically for the UOW/ Repository environment I'm working with. 提出了专门针对我正在使用的UOW /存储库环境的解决方案。

    public static void Increment(short termID)
    {
        termID.ThrowDefault("termID");

        using (var uow = new UnitOfWork(Connection.Products))
        {
            var sql = "Popularity_Update @TermID";
            var parameters = new SqlParameter("TermID", termID);

            uow.Execute(sql, parameters);
        }
    }

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

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