Работа с базой без EntityFramework [требует правки]

210
04 марта 2017, 02:00

Захотелось быстро поработать с Oracle без кучи фреймворковских библиотек. Создаем любой статический класс и добавляем метод:

    /// <summary>
    /// Обернуть таблицу в нужный класс
    /// </summary>
    /// <typeparam name="T">Класс, в который обертываем</typeparam>
    /// <param name="table">Таблица данных</param>
    /// <returns></returns>
    public static List<T> DataTableToList<T>(DataTable table) where T : class, new()
    {
        try
        {
            List<T> list = new List<T>();
            foreach (var row in table.AsEnumerable())
            {
                T obj = new T();
                foreach (var prop in obj.GetType().GetProperties())
                {
                    try
                    {
                        PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
                        Type t = Nullable.GetUnderlyingType(propertyInfo.PropertyType) ?? propertyInfo.PropertyType;
                        object safeValue = (row[prop.Name] == null) ? null : Convert.ChangeType(row[prop.Name], t);
                        propertyInfo.SetValue(obj, safeValue, null);
                    }
                    catch
                    {
                        continue;
                    }
                }
                list.Add(obj);
            }
            return list;
        }
        catch
        {
            return null;
        }
    }

Далее добавляем следующий метод. Если у нас в классе есть свойство, то нужно проверить есть ли такое поле в базе данных.

    /// <summary>
    /// Проверка свойства в БД
    /// </summary>
    /// <param name="prop">Имя свойства</param>
    /// <param name="TBLNAME">Таблица в БД</param>
    /// <param name="OWNER">Схема</param>
    /// <returns></returns>
    public static bool CheckProperty(PropertyInfo prop, string TBLNAME, string OWNER)
    {
        bool res = false;
        using (var conn = new OracleConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
        {
            conn.Open();
            using (var cmd = new OracleCommand())
            {
                cmd.Connection = conn;
                cmd.CommandText = "SELECT COLUMN_NAME FROM ALL_TAB_COLUMNS WHERE OWNER = '" + OWNER + "' AND TABLE_NAME = '" + TBLNAME + "' AND COLUMN_NAME = '" + prop.Name + "'";
                using (OracleDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                {
                    if (reader.HasRows)
                    {
                        res = true;
                    }
                }
            }
        }
        return res;
    }

Далее создаем метод на все случаи жизни (SELECT,INSERT,UPDATE,DELETE).

    /// <summary>
    /// Универсальная функция преобразования данных
    /// </summary>
    /// <typeparam name="T">Класс</typeparam>
    /// <param name="mode">Режим (0-select,1-insert,2-update,3-delete)</param>
    /// <param name="TBLNAME">Таблица в БД</param>
    /// <param name="obj">Экземпляр класса</param>
    /// <param name="ST">Параметр успешного выполнения</param>
    /// <param name="MES">Сообщение об ошибке</param>
    /// <param name="tb">Таблица данных</param>
    /// <param name="WHERECLAUSE">Условие</param>
    /// <param name="FIELDLIST">Набор полей</param>
    /// <param name="SEQNAME">Имя последовательности</param>
    /// <param name="ROWNUM">Количество строк по умолчанию все</param>
    /// <param name="OWNER">Схема</param>
    /// <returns></returns>
    public static bool GetInsertUpdateDelete<T>(int mode, string TBLNAME, T obj, out int ST, out string MES, out DataTable tb, string WHERECLAUSE = null, string FIELDLIST = null, string SEQNAME = null, int ROWNUM = -1, string OWNER = "NSKFND")
    {
        ST = 0;
        MES = "";
        tb = new DataTable();
        bool res = false;
        switch (mode)
        {
            case 0:
                var get = "SELECT ";
                if (string.IsNullOrEmpty(FIELDLIST))
                {
                    foreach (var prop in obj.GetType().GetProperties())
                    {
                        try
                        {
                            PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
                            if (CheckProperty(propertyInfo, TBLNAME, OWNER))
                            {
                                get += propertyInfo.Name + ",";
                            }
                        }
                        catch
                        {
                            continue;
                        }
                    }
                    get = get.Remove(get.Length - 1, 1) 
                        + " FROM " + OWNER + "." + TBLNAME 
                        + (string.IsNullOrEmpty(WHERECLAUSE) ? (ROWNUM == -1 ? "" : " WHERE ROWNUM < " + ROWNUM.ToString()) : " WHERE " + WHERECLAUSE 
                        + (ROWNUM == -1 ? "" : " AND ROWNUM < " + ROWNUM.ToString()));
                }
                else
                {
                    get += FIELDLIST 
                        + " FROM " + OWNER + "." + TBLNAME 
                        + (string.IsNullOrEmpty(WHERECLAUSE) ? (ROWNUM == -1 ? "" : " WHERE ROWNUM < " + ROWNUM.ToString()) : " WHERE " + WHERECLAUSE 
                        + (ROWNUM == -1 ? "" : " AND ROWNUM < " + ROWNUM.ToString()));
                }
                try
                {
                    using (var conn = new OracleConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
                    {
                        conn.Open();
                        using (var cmd = new OracleCommand())
                        {
                            cmd.Connection = conn;
                            cmd.CommandText = get;
                            using (OracleDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                            {
                                if (reader.HasRows)
                                {
                                    tb.Load(reader);
                                }
                                res = true;
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    ST = -1;
                    MES = e.Message;
                    tb = null;
                }
                break;
            case 1:
                var insertfld = "INSERT INTO " + OWNER + "." + TBLNAME + " (";
                var insertval = " VALUES(";
                tb = null;
                foreach (var prop in obj.GetType().GetProperties())
                {
                    try
                    {
                        PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
                        if (CheckProperty(propertyInfo, TBLNAME, OWNER))
                        {
                            insertfld += propertyInfo.Name + ",";
                            insertval += ":" + propertyInfo.Name + ",";
                        }
                    }
                    catch
                    {
                        continue;
                    }
                }
                var transaction = insertfld.Remove(insertfld.Length - 1, 1) + ")" + insertval.Remove(insertval.Length - 1, 1) + ")";
                try
                {
                    using (var conn = new OracleConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
                    {
                        conn.Open();
                        using (var cmd = new OracleCommand())
                        {
                            cmd.Connection = conn;
                            cmd.CommandText = transaction;
                            foreach (var prop in obj.GetType().GetProperties())
                            {
                                try
                                {
                                    PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
                                    if (CheckProperty(propertyInfo, TBLNAME, OWNER))
                                    {
                                        if (propertyInfo.Name == "ID")
                                        {
                                            var NEXT = GetSeq(SEQNAME,OWNER);
                                            propertyInfo.SetValue(obj, Convert.ChangeType(NEXT, propertyInfo.PropertyType), null);
                                            ST = (int)NEXT;
                                        }
                                        var val = propertyInfo.GetValue(obj, null);
                                        try
                                        {
                                            var d = DateTime.ParseExact(val.ToString(), "dd.MM.yyyy HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
                                            OracleParameter dt = new OracleParameter(propertyInfo.Name, OracleDbType.TimeStamp, ParameterDirection.Input);
                                            dt.Value = d;
                                            cmd.Parameters.Add(dt);
                                        }
                                        catch
                                        {
                                            try
                                            {
                                                var d = DateTime.ParseExact(val.ToString(), "dd.MM.yyyy", System.Globalization.CultureInfo.InvariantCulture);
                                                OracleParameter dt = new OracleParameter(propertyInfo.Name, OracleDbType.Date, ParameterDirection.Input);
                                                dt.Value = d;
                                                cmd.Parameters.Add(dt);
                                            }
                                            catch
                                            {
                                                cmd.Parameters.Add(propertyInfo.Name, val);
                                            }
                                        }
                                    }
                                }
                                catch
                                {
                                    continue;
                                }
                            }
                            cmd.ExecuteNonQuery();
                            res = true;
                        }
                    }
                }
                catch (Exception e)
                {
                    ST = -1;
                    MES = e.Message;
                }
                break;
            case 2:
                var update = "UPDATE " + OWNER + "." + TBLNAME + " SET ";
                tb = null;
                foreach (var prop in obj.GetType().GetProperties())
                {
                    try
                    {
                        PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
                        if (CheckProperty(propertyInfo, TBLNAME, OWNER))
                        {
                            update += propertyInfo.Name + " = :" + propertyInfo.Name + ",";
                        }
                    }
                    catch
                    {
                        continue;
                    }
                }
                update = update.Remove(update.Length - 1, 1) + " WHERE " + WHERECLAUSE;
                try
                {
                    using (var conn = new OracleConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
                    {
                        conn.Open();
                        using (var cmd = new OracleCommand())
                        {
                            cmd.Connection = conn;
                            cmd.CommandText = update;
                            foreach (var prop in obj.GetType().GetProperties())
                            {
                                try
                                {
                                    PropertyInfo propertyInfo = obj.GetType().GetProperty(prop.Name);
                                    if (CheckProperty(propertyInfo, TBLNAME, OWNER))
                                    {
                                        if (propertyInfo.Name == "ID")
                                        {
                                            var id = propertyInfo.GetValue(obj, null);
                                            ST = int.Parse(id.ToString());
                                        }
                                        var val = propertyInfo.GetValue(obj, null);
                                        try
                                        {
                                            var d = DateTime.ParseExact(val.ToString(), "dd.MM.yyyy HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
                                            OracleParameter dt = new OracleParameter(propertyInfo.Name, OracleDbType.TimeStamp, ParameterDirection.Input);
                                            dt.Value = d;
                                            cmd.Parameters.Add(dt);
                                        }
                                        catch
                                        {
                                            try
                                            {
                                                var d = DateTime.ParseExact(val.ToString(), "dd.MM.yyyy", System.Globalization.CultureInfo.InvariantCulture);
                                                OracleParameter dt = new OracleParameter(propertyInfo.Name, OracleDbType.Date, ParameterDirection.Input);
                                                dt.Value = d;
                                                cmd.Parameters.Add(dt);
                                            }
                                            catch
                                            {
                                                try
                                                {
                                                    var d = DateTime.ParseExact(val.ToString(), "dd.MM.yyyy H:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
                                                    OracleParameter dt = new OracleParameter(propertyInfo.Name, OracleDbType.TimeStamp, ParameterDirection.Input);
                                                    dt.Value = d;
                                                    cmd.Parameters.Add(dt);
                                                }
                                                catch
                                                {
                                                    cmd.Parameters.Add(propertyInfo.Name, val);
                                                }
                                            }
                                        }
                                    }
                                }
                                catch
                                {
                                    continue;
                                }
                            }
                            cmd.ExecuteNonQuery();
                            res = true;
                        }
                    }
                }
                catch (Exception e)
                {
                    ST = -1;
                    MES = e.Message;
                }
                break;
            case 3:
                var delete = "DELETE FROM " + OWNER + "." + TBLNAME + " WHERE " + WHERECLAUSE;
                try
                {
                    using (var conn = new OracleConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
                    {
                        conn.Open();
                        using (var cmd = new OracleCommand())
                        {
                            cmd.Connection = conn;
                            cmd.CommandText = delete;
                            cmd.ExecuteNonQuery();
                            res = true;
                        }
                    }
                }
                catch (Exception e)
                {
                    ST = -1;
                    MES = e.Message;
                }
                break;
        }
        return res;
    }

Ну вот и все. Использование...

public partial class LookUpClass
{
    public string DESCRIPTION { get; set; }
}
[MetadataType(typeof(Rules_Metadata))]
public partial class Rules
{
    public decimal ID { get; set; }
    public string NAME { get; set; }
    public string CODE { get; set; }
    public string DESCRIPTION { get; set; }
}
internal partial class Rules_Metadata
{
    [DisplayName("Идентификатор")]
    [Required(ErrorMessage = "Поле должно быть заполнено")]
    public decimal ID { get; set; }
    [DisplayName("Наименование")]
    [Required(ErrorMessage = "Поле должно быть заполнено")]
    public string NAME { get; set; }
    [DisplayName("Код")]
    [Required(ErrorMessage = "Поле должно быть заполнено")]
    public string CODE { get; set; }
    [DisplayName("Примечание")]
    public string DESCRIPTION { get; set; }
}
[MetadataType(typeof(RulesDetails_Metadata))]
public partial class RulesDetails
{
    public decimal ID { get; set; }
    public Nullable<decimal> RULEID { get; set; }
    public Nullable<decimal> REPFOLDER { get; set; }
    public Nullable<decimal> REPREPORT { get; set; }
    public decimal ACTIVE { get; set; }
    public string MODIFYDATE { get; set; }
    public decimal MODIFYBY { get; set; }
    public string DESCRIPTION { get; set; }
}
internal partial class RulesDetails_Metadata
{
    [DisplayName("Идентификатор")]
    [Required(ErrorMessage = "Поле должно быть заполнено")]
    public decimal ID { get; set; }
    [DisplayName("Правило")]
    [Required(ErrorMessage = "Поле должно быть заполнено")]
    public Nullable<decimal> RULEID { get; set; }
    [DisplayName("Папка отчета")]
    [Required(ErrorMessage = "Поле должно быть заполнено")]
    public Nullable<decimal> REPFOLDER { get; set; }
    [DisplayName("Отчет")]
    public Nullable<decimal> REPREPORT { get; set; }
    [DisplayName("Активный")]
    public decimal ACTIVE { get; set; }
    [DisplayName("Дата изменения")]
    [DataType(DataType.Date)] //DateTime для времени
    [DisplayFormat(DataFormatString = "dd.MM.yyyy ")] //hh:mm для времени
    [Required(ErrorMessage = "Поле должно быть заполнено")]
    public string MODIFYDATE { get; set; }
    [DisplayName("Автор")]
    [Required(ErrorMessage = "Поле должно быть заполнено")]
    public decimal MODIFYBY { get; set; }
    [DisplayName("Примечание")]
    public string DESCRIPTION { get; set; }
}
[MetadataType(typeof(Permis_Metadata))]
public partial class Permis
{
    public decimal ID { get; set; }
    public Nullable<decimal> STUFFID { get; set; }
    public Nullable<decimal> USERID { get; set; }
    public Nullable<decimal> RULEID { get; set; }
    public decimal ACTIVE { get; set; }
    public string MODIFYDATE { get; set; }
    public decimal MODIFYBY { get; set; }
    public string DESCRIPTION { get; set; }
}
internal partial class Permis_Metadata
{
    [DisplayName("Идентификатор")]
    [Required(ErrorMessage = "Поле должно быть заполнено")]
    public decimal ID { get; set; }
    [DisplayName("Должность")]
    [Required(ErrorMessage = "Поле должно быть заполнено")]
    public Nullable<decimal> STUFFID { get; set; }
    [DisplayName("Пользователь")]
    public Nullable<decimal> USERID { get; set; }
    [DisplayName("Правило")]
    [Required(ErrorMessage = "Поле должно быть заполнено")]
    public Nullable<decimal> RULEID { get; set; }
    [DisplayName("Активный")]
    public decimal ACTIVE { get; set; }
    [DisplayName("Дата изменения")]
    [DataType(DataType.Date)] //DateTime для времени
    [DisplayFormat(DataFormatString = "dd.MM.yyyy ")] //hh:mm для времени
    [Required(ErrorMessage = "Поле должно быть заполнено")]
    public string MODIFYDATE { get; set; }
    [DisplayName("Автор")]
    [Required(ErrorMessage = "Поле должно быть заполнено")]
    public decimal MODIFYBY { get; set; }
    [DisplayName("Примечание")]
    public string DESCRIPTION { get; set; }
}
public class FReportPermissionController : CController
{

    [PartialAuthorize]
    public ActionResult RuleEdit_(decimal? id)
    {
        var ST = 0;
        var MES = "";
        DataTable pseudo = null;
        if (ODDA.GetInsertUpdateDelete(0, "SME_RULES", new Rules(), out ST, out MES, out pseudo, "ID = " + id.ToString()))
        {
            var model = ODDA.DataTableToList<Rules>(pseudo);
            return PartialView(model[0]);
        }
        else
        {
            return NotAjaxFormAlert("getNewTost('" + MES + "','error');");
        }
    }
    [HttpPost]
    [PartialAuthorize]
    public ActionResult RuleEdit_(Rules model)
    {
        var ST = 0;
        var MES = "";
        DataTable pseudo = null;
        if (ModelState.IsValid)
        {
            ODDA.GetInsertUpdateDelete(2, "SME_RULES", model, out ST, out MES, out pseudo, "ID = " + model.ID.ToString());
            return InvertCheckTransactionState(ST, MES, 2, "/FReportPermission/Index?IdName=" + ST.ToString());
        }
        else
        {
            return PartialView(model);
        }
    }
}

Ну и вьюшка на метод public ActionResult RuleEdit_(decimal? id)

@* Модальная форма редактирования правила *@
@model FFI.Controllers.Rules
<div class="modal-header">
    @* Копка в углу формы для ее закрытия *@
    <button type="button" class="close" data-dismiss="modal">
        <span aria-hidden="true">×</span>
        <span class="sr-only">Close</span>
    </button>
    @* Заголовок модальной формы *@
    <h4 class="modal-title">@MyHelpers.GetTranslation("Редактировать правило доступа")</h4>
</div>
@using (Html.FFIForm("/FReportPermission/RuleEdit_", "#valmodal", OnBegin: "buttonLadda.ladda('start');", OnSuccess: "ReloadPartial(); RefreshButtonStateModal(validationModal);", cssclass: "newValidateUpdateRule"))
{
    <div class="modal-body form-horizontal formPut clearfix">
        @Html.FFInput(model => model.ID, lableClass: "col-lg-2 col-md-2 col-sm-4 col-xs-4", secondDivClass: "col-lg-10 col-md-10 col-sm-8 col-xs-8", forCreate:false, ForEdit:false)
        @Html.FFInput(model => model.NAME, lableClass: "col-lg-2 col-md-2 col-sm-4 col-xs-4", secondDivClass: "col-lg-10 col-md-10 col-sm-8 col-xs-8")
        @Html.FFInput(model => model.CODE, lableClass: "col-lg-2 col-md-2 col-sm-4 col-xs-4", secondDivClass: "col-lg-10 col-md-10 col-sm-8 col-xs-8")
        @Html.FFInput(model => model.DESCRIPTION, lableClass: "col-lg-2 col-md-2 col-sm-4 col-xs-4", secondDivClass: "col-lg-10 col-md-10 col-sm-8 col-xs-8")
    </div>
    <div class="modal-footer">
        <button type="button" class="btn btn-white evBtnCancelAll" data-dismiss="modal">@MyHelpers.GetTranslation("Отмена")</button>
        @* Элемент лада кнопки *@
        <button type="submit" class="btn btn-primary ladda-button ladda-button-submit evBtnUpdateAll" data-style="expand-right">@MyHelpers.GetTranslation("Обновить")</button>
    </div>
}

Вот еще несколько вспомогательных методов для полноты картины

    /// <summary>
    /// Получить уникальный ID с любого секвенсера
    /// </summary>
    /// <param name="seqname">Имя последовательности</param>
    /// <param name="OWNER">Схема</param>
    /// <returns></returns>
    public static decimal GetSeq(string seqname, string OWNER)
    {
        decimal res = 0;
        using (var conn = new OracleConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
        {
            conn.Open();
            using (var cmd = new OracleCommand())
            {
                cmd.Connection = conn;
                cmd.CommandText = "SELECT " + OWNER + "." + seqname + ".NEXTVAL FROM DUAL";
                using (OracleDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                {
                    if (reader.HasRows)
                    {
                        reader.Read();
                        res = decimal.Parse(reader[0].ToString());
                    }
                }
            }
        }
        return res;
    }
    /// <summary>
    /// Получить REF_CURSOR из любой процедуры в виде таблицы
    /// </summary>
    /// <param name="refproc">Процедура в БД</param>
    /// <param name="param">Список параметров</param>
    /// <param name="OWNER">Схема</param>
    /// <returns></returns>
    public static DataTable ExecuteProcForRefCursor(string refproc, List<OracleParameter> param, string OWNER = "NSKFND")
    {
        DataTable tbl = new DataTable();
        using (var conn = new OracleConnection(System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
        {
            conn.Open();
            using (var cmd = new OracleCommand())
            {
                cmd.Connection = conn;
                cmd.CommandText = OWNER + "." + refproc;
                cmd.CommandType = CommandType.StoredProcedure;
                foreach (var item in param)
                {
                    cmd.Parameters.Add(item);
                }
                using (OracleDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                {
                    if (reader.HasRows)
                    {
                        tbl.Load(reader);
                    }
                }
            }
        }
        return tbl;
    }

Хотелось бы узнать мнение сообщества по данной теме. Для поддержания EF(EntityFramework) нужно тратить много времени, конечно он хорош, когда в БД(База данных) таблиц не более 200. Если же больше он становится просто обузой, с которой очень трудно работать. Выше представлена моя альтернатива...Удачи всем!

READ ALSO
Отключение сертификата SSL для LibGit2Sharp

Отключение сертификата SSL для LibGit2Sharp

Доброго времени суток!

271
Формирование Dacpac программно

Формирование Dacpac программно

Условие: Имеется несколько Database Project проектовВ каждом своя схема одной БД

330