Menu

Entity Framework Core extension to Execute Stored procedure and get results back

Since Entity Framework Core is fairly new (at the time I am writing) and still under development. Not most of the required features are not there out of the box and you will have to write extensions. I have to utilise an existing stored procedure to get some data from database. I have to use ADO for this, Create a file name DatabaseContextExtensions.cs and paste below code.

public static class DatabaseContextExtensions
{
    public static List<T> CollectionFromSql<T>(this DbContext dbContext, string sql, Dictionary<string, object> parameters) where T : class, new()
    {
        using (var cmd = dbContext.Database.GetDbConnection().CreateCommand())
        {
            cmd.CommandText = sql;
            if (cmd.Connection.State != ConnectionState.Open)
                cmd.Connection.Open();

            foreach (KeyValuePair<string, object> param in parameters)
            {
                DbParameter dbParameter = cmd.CreateParameter();
                dbParameter.ParameterName = param.Key;
                dbParameter.Value = param.Value;
                cmd.Parameters.Add(dbParameter);
            }

            List<T> results = null;
            using (var dataReader = cmd.ExecuteReader())
            {
                results = DataReaderMapToList<T>(dataReader);
            }

            return results;
        }
    } 
    
    public static List<T> DataReaderMapToList<T>(IDataReader dr)
    {
        List<T> list = new List<T>();
        T obj = default(T);
        while (dr.Read())
        {
            obj = Activator.CreateInstance<T>();
            foreach (PropertyInfo prop in obj.GetType().GetProperties())
            {
                if (!object.Equals(dr[prop.Name], DBNull.Value))
                {
                    prop.SetValue(obj, dr[prop.Name], null);
                }
            }
            list.Add(obj);
        }
        return list;
    }   
}

And this is the usage.

public User GetUserName(string emailAddress)
{
    var user = _context.CollectionFromSql<User>("[dbo].[GetUser] @EmailAddress",
        new Dictionary<string, object>
        {
            { "@EmailAddress", emailAddress }
        }).ToList().FirstOrDefault();

    return user;
}

 

Leave a comment