2

Database

I have Stored Procedure name GetAllCustomer


I have Stored Procedure in the EntityFramework 6x and in Project ASP.NET MVC5.

I'm using by calling db.GetAllCustomer.ToList();

But in the EntityFramework Core it's not rendering DbSet and I need to create it manually. It can't use EF 6x.

Here is the image of my works:

enter image description here

Is there a way to call Stored Procedure as simple as EF 6x??

Darko Kenda
  • 4,781
  • 1
  • 28
  • 31

2 Answers2

2

EF Core Power Tools can map stored procedures for you, it is not a built in feature of EF Core.

Sample user code:

using (var db = new NorthwindContext())
{
        var procedures = new NorthwindContextProcedures(db);

        var orders = await procedures.CustOrderHist("ALFKI");
        foreach (var order in orders)
            Console.WriteLine($"{order.ProductName}: {order.Total}");

        var outOverallCount = new OutputParameter<int?>();
        var customers = await procedures.SP_GET_TOP_IDS(10, outOverallCount);
        Console.WriteLine($"Db contains {outOverallCount.Value} Customers.");
        foreach (var customer in customers)
            Console.WriteLine(customer.CustomerId);
}

Read more here: https://github.com/ErikEJ/EFCorePowerTools/wiki/Reverse-Engineering#sql-server-stored-procedures

ErikEJ
  • 40,951
  • 5
  • 75
  • 115
1

You can use custom ExecuteQuery in your context for any use including stored procedure.

public List<T> ExecuteQuery<T>(string query) where T : class, new()
{
        using (var command = Context.Database.GetDbConnection().CreateCommand())
        {
            command.CommandText = query;
            command.CommandType = CommandType.Text;

            Context.Database.OpenConnection();
            List<T> result;

            using (var reader = command.ExecuteReader())
            {
                result = new List<T>();
                var columns = new T().GetType().GetProperties().ToList();

                while (reader.Read())
                {
                    var obj = new T();

                    for (var i = 0; i < reader.FieldCount; i++)
                    {
                        var name = reader.GetName(i);
                        var prop = columns.FirstOrDefault(a => a.Name.ToLower().Equals(name.ToLower()));

                        if (prop == null)
                            continue;

                        var val = reader.IsDBNull(i) ? null : reader[i];
                        prop.SetValue(obj, val, null);
                    }

                    result.Add(obj);
                }

                return result;
            }
        }
    }

Usage:

db.ExecuteQuery<YOUR_MODEL_DEPEND_ON_RETURN_RESULT>("SELECT FIELDS FROM YOUR_TABLE_NAME")
db.ExecuteQuery<YOUR_MODEL_DEPEND_ON_RETURN_RESULT>("EXEC YOUR_SP_NAME")
db.ExecuteQuery<YOUR_MODEL_DEPEND_ON_RETURN_RESULT>("EXEC YOUR_SP_NAME @Id = 10")

To reduce errors, create query string easier and do faster, I use several other methods, and I put stored procedures names in a static class.

For example, I have something like this to get customer list:

    /// <param name="parameters">The model contains all SP parameters</param>
    public List<customerGetDto> Get(CustomerSpGetParameters parameters = null)
    {
        //StoredProcedures.Customer.Get Is "sp_GetAllCustomers"
        //CreateSqlQueryForSp creates a string with stored procedure name and parameters
        var query = _publicMethods.CreateSqlQueryForSp(StoredProcedures.Request.Get, parameters);
        //For example, query= "Exec sp_GetAllCustomers @active = 1,@level = 3,...."
        return _unitOfWork.ExecuteQuery<RequestGetDto>(query);
    }
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Hamed Rashno
  • 314
  • 1
  • 2
  • 9