Click here to Skip to main content
15,886,017 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I've been using EF6 code-first approach on a new project, and it has been wonderful, but now I struggling a bit on how to customized the CRUD stored procedures, so that some columns are computed in the database.

Process (abstract):
public abstract class Process
{
    public int Id {get; set}
    public int Name {get; set}
    public DateTime CreateDate{get; private set}
    public DateTime UpdateDate{get; private set}

    public virtual ICollection<ProcessContact> Contacts { get; set; }
}

ProcessContact:
public class ProcessContact
{
    public string Name {get; set}
    public string Value {get; set}
}

ProcessA:
public class ProcessA: Process
{
    public int A {get; set}
}

ProcessB:
public class ProcessB: Process
{
    public int B {get; set}
}

Given the 4 classes above as an example how can I in EF6 code-first, customized the generated stored procedure so it can for example:

-> On insert of Process, set the Id as count(*)+1 and CreateDate = GETUTCTIME()
-> On update of ProcessContact, set UpdateDate = GETUTCTIME() in the Process table

Thanks

What I have tried:

I´ve been looking at migrations, but to be honest I´m struggling a bit with it.
Posted
Updated 11-Aug-18 9:04am

1 solution

First, EF does not generate stored procedures. Everything is done through normal SQL statements.

Next, your idea of "count(*) + 1" to generate a record ID value is ridiculous and degrades in performance over time as the number of records increases. Record ID values should be database generated, not programmed via formula. This is quite easily done in EF as it's just an attribute to add to the field you're using, like:
C#
public abstract class Process
{
    [Key]
    public int Id {get; set}
    public int Name {get; set}
    public DateTime CreateDate{get; private set}
    public DateTime UpdateDate{get; private set}

    public virtual ICollection<ProcessContact> Contacts { get; set; }
}

or by convention. EF assumes the key is specified by the class name with "Id" appended to it:
C#
public abstract class Process
{
    public int ProcessId {get; set}
    public int Name {get; set}
    public DateTime CreateDate{get; private set}
    public DateTime UpdateDate{get; private set}

    public virtual ICollection<ProcessContact> Contacts { get; set; }
}


The Update datetime field can be done in a few different ways. EF6 can use stored procedures to perform database operations. YOU have to write the stored procedures, bake them into the database, and then tell EF how to use it.

Or, you can just set the field in your C# code and send the update to the database using normal SaveChanges in your EF context.
 
Share this answer
 
Comments
Member 13315405 11-Aug-18 16:14pm    
Dave thank you for your reply. I understand the overhead on using count(*) + 1 but in some cases I need the number to be sequential, and identity() doesn´t guarantee that.
Regarding your statement "tell EF how to use it", that´s my problem ...
I´ve read an article where they use and sql file on Migrations to replace the EF generated stored procedures, but I was trying to do it in code.

Sorry for the dumb questions, but I´m new to this. Any advice ?
Dave Kreskowiak 12-Aug-18 20:15pm    
You either don't seem to know what a stored procedure is or you're not listening.

EF NEVER GENERATES STORED PROCEDURES.

It generates an SQL statement to execute queries against the database. Single statements are NOT stored procedures.

Tutorial on using a stored procedure in EF: Use Stored Procedure in Entity Framework[^]
Member 13315405 15-Aug-18 8:07am    
Dave, I too question my programming skills, but I don´t think what you say is true.
If you see this link I can tell EF6 (not EF Core) to generate the stored procedures.
Dave Kreskowiak 15-Aug-18 8:58am    
HAHAHAHA! It STILL doesn't GENERATE stored procedures. YOU have to supply the stored procedure code. You can then use EF to create the stored procedure object in the database. All EF does is put what you supplied into a shell of a CREATE PROCEDURE statement, or whatever command the engine uses, in the database engine.

Why? Because EF actually doesn't know jack sh*t about how to generate an SQL statement. It builds an expression tree that describes the intent of what it wants to do. The underlying EF-compatible, database vendor supplied database provider translates the expression tree into an engine specific representation of what EF wants. There is no expression tree for an entire stored procedure.

YOU have to supply the engine-specific stored procedure code, the parameter specs and field mappings in the body of the CreateStoredProcedure statement in EF.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900