• 1400/03/09

تداخل ef core و db first :

سلام استاد

با تشکر از آموزش های خوب شما

بنده تا حدی نسبت به کار با بانک اطلاعاتی اطلاعات دارم اما در غالب آموزش ها شما از code first استفاده می کنید تا جایی که رغبت پیدا کردم این سیستم رو یاد بگیرم و ازش در پروژه های خودم استفاده کنم.

اما احساس می کنم با استفاده از code first خیلی از امکانات sql رو از دست میدم.

با مشاهده این دوره این نظرم تقویت شد.

آیا این دو راه (code first و db first) با هم قابل ترکیب است یا در هر پروژه از یکی فقط باید استفاده کنیم؟

اگر کمی تخصصی تر راهنمایی کنید ممنون میشم.

با تشکر

  • 1400/03/09
  • ساعت 16:58

سلام 

با توجه به اینکه شما این دوره را تهیه کردید به شدت توصیه میکنم از Dapper و Db First استفاده کنید 

مطمئن باشید پشیمان نخواهید شد 


  • 1400/03/10
  • ساعت 13:28

ممنون از راهنمایی تون

باز هم عذر خواهی می کنم، بنده تا قبل از آموزش هایی که ببینم از این کلاس ها رو خودم طراحی کردم از این ها برای واکشی اطلاعات استفاده می کردم.

البته تمام خروجی های بانک اطلاعاتی رو در قالب procedure طراحی کرده ام که به نظر خودم خیلی کار رو در نرم افزار راحت و ساده و قابل توسعه تر کرده بود.

فقط می خواهم ببینم این روش قابل رقابت با dapper هست و با وجود این روش نیازی به جایگزینی روش کارم وجود دارد؟

البته توقعی ندارم که حتماً به این سوال بنده پاسخ بدید چون می دونم مشاهده مستندات نیازمند وقت گذاشتن هست و شما هم الحمدلله خیلی در حال آموزش و کارهای مختلفی هستید که خدمات زیادی برای دوستان به همراه دارد.

در هر حال اگر فرصت نداشتید بررسی کنید باز هم دعا تون می کنم.

1. ابتدا یک کلاس استاتیک ایجاد کردم که به صورت داینامیک string اجرای  هر procedure ی رو با دریافت نام schema و نام procedure و پارامترهای procedure ایجاد می کند.

 

public class DB
    {
        // ساخت دستور اجرای پروسیژر برای ارسال به بانک
        // ورودی ها:
        // 1. نام schema
        // 2. نام پروسیژر
        // 3. لیست پارامتر های پروسیژر

        // خروجی:
        // استرینگ اجرای پروسیژر برای ارسال به بانک اطلاعاتی
        public static string setQuery(string schema, string procedureName, List<Param> param)
        {

            string name = "EXEC [" + schema + "].[" + procedureName + "] ";
            int i = 0;
            int e = param.Count;
            foreach (var item in param)
            {
                if (item.type == typeof(int))
                {
                    name += i < e - 1 ? item.value + " ," : item.value;
                }
                else
                {
                    name += i < e - 1 ? "N'" + item.value + "' ," : "N'" + item.value + "'";
                }
                i++;
            }
            return name;
        }
    }

    // کلاس مربوط به ایجاد پارامترهای پروسیژر
    public class Param
    {
        public Param()
        {
        }

        public Param(Type type, object value)
        {
            this.type = type;
            this.value = value;
        }

        public Type type { get; set; }
        public object value { get; set; }
    }
}

 

2. یک کلاس ایجاد می کنیم که با دریافت string اجرای procedure بصورت async یک datatable از بانک دریافت می کند.

public class GetDataSet
    {
        
        private string connectionString = "Data Source=.;Initial Catalog=dbName;User ID=userName;Password=pass;MultipleActiveResultSets=True";
        private string Query;

        // return dataTable as async
        public async Task<DataTable> DataTable(string query)
        {
            Query = query;
            Task<DataTable> dt_ = new Task<DataTable>(Data_);
            dt_.Start();
            return await dt_;
        }

        // دریافت یک dataTable
        private DataTable Data_()
        {
            SqlConnection connection = new SqlConnection(connectionString);
            SqlCommand cmd;
            DataTable dt = new DataTable();
            SqlDataAdapter da = new SqlDataAdapter();
            try
            {
                connection.Open();
                cmd = new SqlCommand(Query, connection);
                da.SelectCommand = cmd;
                da.Fill(dt);
            }
            catch (Exception ex)
            {
            }
            finally
            {
                connection.Close();
                connection.Dispose();
            }
            return dt;
        }

    } 

 

3. به شکل زیر از این دو کلاس بصورت داینامیک استفاده می کنیم

[Route("api/[controller]")]
    [ApiController]
    public class usage : ControllerBase
    {
        GetDataSet ds = new GetDataSet();
       
        [HttpGet]
        public async Task<IActionResult> GetSettingArz(int schoolID)
        {
            try
            {
                // ایجاد لیست پارامتر های پروسیژر
                List<Param> param = new List<Param>();
                param.Add(new Param(typeof(int), schoolID));
                // اجرای کوئری و ذخیره در دیتا تیبل
                DataTable dataTable = await ds.DataTable(DB.setQuery("exam", "GetSettingArz", param));
                DataRow item = dataTable.Rows[0];
                // تبدیل دیتاتیبل به لیست
                SettingArzyabiModel list = new SettingArzyabiModel()
                {
                    timeArzyabi = Convert.ToInt32(item["timeArzyabi"]),
                    veryGoodGrade = Convert.ToInt32(item["veryGoodGrade"]),
                    goodGrade = Convert.ToInt32(item["goodGrade"]),
                    midGrade = Convert.ToInt32(item["midGrade"]) ,
                    badGrade = Convert.ToInt32(item["badGrade"]),
                    veryBadGrade = Convert.ToInt32(item["veryBadGrade"]),
                    studentsSeeResults = Convert.ToBoolean(item["studentsSeeResults"])
                };
                return Ok(list);
            }
            catch (Exception ex)
            {
                return Ok(new List<SettingArzyabiModel>());
            }
        }

        [HttpPost]
        public async Task<IActionResult> saveEditDurationArz(int schoolID, bool studentsSeeResults)
        {
            try
            {
                // ایجاد لیست پارامتر های پروسیژر
                List<Param> param = new List<Param>();
                param.Add(new Param(typeof(int), schoolID));
                param.Add(new Param(typeof(bool), studentsSeeResults));
                // اجرای کوئری و ذخیره در دیتا تیبل
                DataTable dataTable = await ds.DataTable(DB.setQuery("exam", "editStudentsSeeResults", param));
                // دریافت نتیجه پست
                Id_ValueList list = new Id_ValueList();
                DataRow row = dataTable.Rows[0];
                list.id = Convert.ToInt32(row["messageID"]);
                list.value = row["message"].ToString();
                return Ok(list);
            }
            catch (Exception ex)
            {
                return Ok(new Id_ValueList());
            }
        }
    }

logo-samandehi