0

I have to use the Code Second approach with EF6, because I have a database where many of use cases are already implemented in stored procedures. As a newbie in EF, I try to figure out what the correct way to use stored procedures with EF6 is when the SP is not a fully update SP but only changes the object partially. Unfortunately, most samples I could find on the internet (and also this question) using SP with EF6 are simple CRUD statements. But I am facing a different problem. To describe the problem, I show you a simple example: Let's say, I have the following simple table:

CREATE TABLE WORK_OBJECT
(
  ID                          NUMBER,
  STATUS_ID                   NUMBER,
  DEPARTMENT                  NUMBER,
  PRODUCT_NAME                VARCHAR2(100 BYTE),
)

Now I have a use case called "Lock Workobject" which is written as a stored procedure:

PROCEDURE Do_Lock
        (  pn_Work_Object_ID   IN  WORK_OBJECT.ID%TYPE
        ,  pv_Error_Msg        OUT VARCHAR2
        ,  pn_ErrCode              OUT NUMBER
        )
IS
          cv_proc_name CONSTANT VARCHAR2(30) := 'Do_Lock';
BEGIN
    UPDATE WORK_OBJECT  SET    STATUS_ID = 400 WHERE  ID        = pn_Work_Object_ID AND STATUS_ID = 300;
    Log(...)
    EXCEPTION
      WHEN WOB_Wrong_Status THEN
          pn_ErrCode   := -111;
          pv_Error_Msg := 'Unable to lock';
END Do_Lock;

It does nothing more than changing the status of a data record and also logging in another table and if there is an exception return error message and error code. But it is not a fully update statement of table so I could link it MapToStoredProcedures(s => s.Update...). It is just for this specific use case i.e., locking a workobject. Now in my application I have the entity defined as class:

public class Workobject :Entity<int>,IAggregateRoot
{
    [Column("STATUS_ID")]
    public int StatusId { get; set; }

    [Column("PRODUCT_NAME")]
    public String ProductName { get; set; }
    
    [Column("DEPARTMENT")]
    public int Department {get;set;}    

    public void Lock()
    {
        // Here I have to call SP Do_Lock via EF
    }
}
        

Now, I don't know what the correct way is to call the stored procedure. If I just call the stored procedure with EF via a derived DbContext then STATUS_ID is changed in the database, but Workobject.StatusId remains the same in the code. So should I change StatusId in the C# code manually after calling the SP successfully? That would be very inappropriate, because I have to implement the logic (setting status to 400) again in the C# code. Or should I force EF to reload the object from the database? In that case, the solution would not be optimal from the performance perspective. Thus, what is the correct way to do that with EF6? Is there a standard way to solve that problem?

Code Pope
  • 5,075
  • 8
  • 26
  • 68
  • The duplicate says "code first," but it will work with "database-first." – Robert Harvey Jan 04 '21 at 18:25
  • @RobertHarvey, this question is totally different with the linked question. My question is not how to call a stored procedure using database first or code first approach and I have highlighted this in the text. The question is what the correct way is to also keep the data synchronized when calling an SP which just partially changes the data. So I don't understand why you have closed this question. – Code Pope Jan 04 '21 at 18:44
  • 1
    Is the problem with your Stored Procedure? Because EF6 has nothing to do with that; you simply call the procedure and it executes. https://learn.microsoft.com/en-us/ef/ef6/querying/raw-sql – Robert Harvey Jan 04 '21 at 18:47
  • If you need the updated data from the database after the SP executes, you retrieve that in the usual way. – Robert Harvey Jan 04 '21 at 18:48
  • I have update the question, so that it expresses better the problem. – Code Pope Jan 04 '21 at 18:49
  • Why don't you craft the raw SQL call and your SP in such a way that it returns the updated entit(ies) you need? – Robert Harvey Jan 04 '21 at 18:50
  • @RobertHarvey, by "Retrieving it in the usual way" you mean to reload the object via `DbContext`? – Code Pope Jan 04 '21 at 18:50
  • That would be the idea, yes. – Robert Harvey Jan 04 '21 at 18:51
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/226837/discussion-between-code-pope-and-robert-harvey). – Code Pope Jan 04 '21 at 18:52

0 Answers0