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?