نظرات نظرسنجی‌ها
آیا در کنفرانس‌های توسعه دهندگان داخلی شرکت می‌کنید؟
من خودم خیلی مشتاق شرکت در همچین کنفراس هایی هستم ولی متاسفانه بیشتر رویداد ها  در حوزه استارتاپ ها  و معرفی آنها می‌باشند .
به نظرم کنفراس‌های در حوزه نرم افزار خیلی در روند رشد و آگاهی برنامه نویسان تاثیر داره و اگر اساتید حوزه نرم افزار داخلی در این راستا اقدام کنند کمک بزرگی خواهد بود .
برای  نمونه TehranDb  کار خوب و کاربردی برای افراد فعال در زمینه دیتابیس هستش .
مطالب
اعتبارسنجی در فرم‌های ASP.NET MVC با Remote Validation

بعد از آمدن نسخه‌ی سوم ASP.NET MVC مکانیسمی به نام Remote Validation به آن اضافه شد که کارش اعتبارسنجی از راه دور بود. فرض کنید نیاز است در یک فرم، قبل از اینکه کل فرم به سمت سرور ارسال شود، مقداری بررسی شده و اعتبارسنجی آن انجام گیرد و این اعتبارسنجی چیزی نیست که بتوان سمت کاربر و بدون فرستاده شدن مقداری به سمت سرور صورت گیرد. نمونه بارز این مسئله صفحه عضویت اکثر سایت‌هایی هست که روزانه داریم با آن‌ها کار می‌کنیم. فیلد نام کاربری توسط شما پر شده و بعد از بیرون آمدن از آن فیلد، سریعا مشخص می‌شود که آیا این نام کاربری قابل استفاده برای شما هست یا خیر. به‌صورت معمول برای انجام این کار باید با جاوا اسکریپت، مدیریتی روی فیلد مربوطه انجام دهیم. مثلا با بیرون آمدن فوکوس از روی فیلد، با Ajax نام کاربری وارد شده را به سمت سرور بفرستیم، چک کنیم و بعد از اینکه جواب برگشت بررسی کنیم که الان آیا این نام کاربری قبلا گرفته شده یا نه.
انجام این کار به‌راحتی با مزین‌کردن خصوصیت (Property) مربوطه موجود در مدل برنامه به Attribute یا ویژگی Remote و داشتن یک Action در Controller مربوطه که کارش بررسی وجود یوزرنیم هست امکان پذیر است. ادامه بحث را با مثال همراه می‌کنم.
به عنوان مثال در سیستمی که قرار هست محصولات ما را ثبت کند، باید بیایم و قبل از اینکه محصول جدید به ثبت برسد این عملیات چک‌کردن را انجام دهیم تا کالای تکراری وارد سیستم نشود. شناسه اصلی که برای هر محصول وجود دارد بارکد هست و ما آن را میخواهیم مورد بررسی قرار دهیم.


مدل برنامه

    public class ProductModel
    {
        public int Id { get; set; }

        [Display(Name = "نام کالا")]
        [Required(ErrorMessage = "{0} یک فیلد اجباری است و باید آن را وارد کنید.")]
        [StringLength(50, ErrorMessage = "طول {0} باید کمتر از {1} کاراکتر باشد.")]
        public string Name { get; set; }

        [Display(Name = "قیمت")]
        [Required(ErrorMessage = "{0} یک فیلد اجباری است و باید آن را وارد کنید.")]
        [DataType(DataType.Currency)]
        public double Price { get; set; }

        [Display(Name = "بارکد")]
        [Required(ErrorMessage = "{0} یک فیلد اجباری است و باید آن را وارد کنید.")]
        [StringLength(50, ErrorMessage = "طول {0} باید کمتر از {1} کاراکتر باشد.")]
        [Remote("IsProductExist", "Product", HttpMethod = "POST", ErrorMessage = "این بارکد از قبل در سیستم وجود دارد.")]
        public string Barcode { get; set; }
    }

همونطور که می‌بینید خصوصیت Barcode را مزین کردیم به ویژگی Remote. این ویژگی دارای ورودی‌های خاص خودش هست. وارد کردن نام اکشن و کنترلر مربوطه برای انجام این چک‌کردن از مهم‌ترین قسمت‌های اصلی هست. چیزهایی دیگه‌ای هم هست که می‌توانیم آن‌ها را مقداردهی کنیم. مثل HttpMethod، ErrorMessage و یا AdditionFields. HttpMethod که همان طریقه‌ی ارسال درخواست به سرور هست. ErrorMessage هم همان خطایی هست که در زمان رخ‌داد قرار است نشان داده شود. AdditionFields هم خصوصیتی را مشخص می‌کند که ما می‌خوایم به‌همراه فیلد مربوطه به سمت سرور بفرستیم. مثلا می‌تونیم به‌همراه بارکد، نام کالا را هم برای بررسی‌های مورد نیازمان بفرستیم.


کنترلر برنامه

        [HttpPost]
        [OutputCache(Location = OutputCacheLocation.None, NoStore = true)]
        public ActionResult IsProductExist(string barcode)
        {
            if (barcode == "123456789") return Json(false); // اگر محصول وجود داشت
            return Json(true);
        }

در اینجا به نمایش قسمتی از کنترلر برنامه می‌پردازیم. اکشنی که مربوط می‌شود به چک‌کردن مقدارهای لازم و در پایان آن یک خروجی Json را برمی‌گردانیم که مقدار true یا false دارد. در حقیقت مقدار را به این صورت برمی‌گردانیم که اگر مقدار ورودی در پایگاه داده وجود دارد، false را برمی‌گرداند و اگر وجود نداشت true. همین‌طور آمدیم از کش شدن درخواست‌هایی که با Ajax آمده با ویژگی OutputCache جلوگیری کردیم.

مطالب
MongoDb در سی شارپ (بخش اول)
MongoDb  یک دیتابیس Nosql سندگراست که توسط ++C نوشته شده است و از پشتیبانی خوبی در بسیاری از زبان‌ها برخوردار است. مونگو از ساختاری به نام Bson که ساختاری مشابه Json را دارد استفاده می‌کند؛ با این تفاوت که در Json مبحث دیتاتایپ یا نوع داده وجود ندارد، ولی در Bson دیتاتایپ‌ها تعریف می‌شوند. برای دیدن نوع‌های Bson و نحوه نوشته شدن سند آن می‌توانید مقاله MongoDb#7 را مطالعه بفرمایید.


برای آغاز به کار با این دیتابیس ابتدا باید آن را از سایت اصلی دریافت و بر روی سیستم نصب نمایید. متاسفانه سایت مونگو برای کشور ایران محدودیتی قرار داده است و باید از روش‌های دیگری آن را دریافت نمایید و بر روی سیستم خود نصب نمایید. نحوه نصب این دیتابیس را میتوانید در مقاله MongoDb#3 مشاهده نمایید.

شاید نیاز باشد بجای کار کردن با محیط کنسول این دیتابیس، با یک محیط گرافیکی شبیه آن چیزی که Raven دارد کار کنید وتغییرات را مشاهده نمایید؛ برای همین به این آدرس رفته و محیط دلخواه خود را انتخاب نمایید.

  یک پروژه از نوع کنسول را در ویژوال استادیو ایجاد کنید و سپس درایور رسمی مونگو را از این آدرس یا از طریق nuget نصب نمایید:
Install-Package mongocsharpdriver

ابتدا سه مدل را به شکل زیر ایجاد میکنیم:
  public class Author
    {
        public ObjectId Id { get; set; }
        public string Name { get; set; }
    }

public class Language
    {
        public ObjectId Id { get; set; }
        public string Name { get; set; }
    }

  public class Book
    {
        public ObjectId Id { get; set; }
        public string Title { get; set; }
        public string ISBN { get; set; }
        public int Price { get; set; }
        public List<Author> Authors { get; set; }
        public Language Language { get; set; }
    }

نوع ObjectId، نوعی است که توسط مونگو برای مشخص کردن کلید یکتای سند معرفی میشود.

در خطوط اولیه کد زیر، یک شیء از مدل بالا را ساخته و آن را مقداردهی می‌کنیم:
           var book =new Book()
           {
               Title = "Gone With Wind",
               ISBN = "43442424",
               Price = 50000,
               Language = new Language()
               {
                  Name = "Persian"
               },
               Authors = new List<Author>()
               {
                   new Author()
                   {
                       Name = "Margaret Mitchell"
                   },
                     new Author()
                   {
                       Name = "Ali Mahboobi (Translator)"
                   },
               }
           };

بعد از آن یک شیء کلاینت از نوع mongoClient میسازیم که نوع خروجی آن یک اینترفیس میباشد که توسط کلاسی از جنس آن مقداردهی شده است. بیشتر خروجی‌های مونگو در این کتابخانه از نوع اینترفیس هستند. شیء کلاینت وظیفه دارد تا ارتباط شما را با سرور مونگو برقرار کند:
var client = new MongoClient();
البته در این حالت سرور اتصالی مونگو، سیستم جاری و پورت شماره 27017 فرض میشود. در صورتیکه بخواهید آدرسی غیر از آن را بدهید یا حتی همین آدرس را به طور دستی تعیین کنید، از طریق زیر امکان پذیر است. پارامترهای سازنده این شیء کلاینت میتوانند به صورت رشته‌ای، رشته اتصال را دریافت کنند و یا از طریق شیء MangoClientSettings آن را پاس کنید.
 string connectionString = "mongodb://localhost:27017";
            MongoClientSettings settings = MongoClientSettings.FromUrl(new MongoUrl(connectionString));
            var client = new MongoClient(settings);

در قسمت بعد لازم است که از سرور جاری، دیتابیس خود را دریافت کنیم. در صورتیکه دیتابیس درخواستی وجود نداشته باشد، یک دیتابیس جدید با آن نام ساخته خواهد شد:
var db = client.GetDatabase("publisher");
در نمونه کدهای قدیمی مونگو، قبل از دریافت سرور بایستی شیء Server را از طریق متد GetServer نیز دریافت میکردید که از نسخه دو به بعد، آن را منسوخ اعلام کرده‌اند و همین تنظیمات بالا کفایت میکند.
در مونگو اصطلاحی به نام collection وجود دارد که اسناد در آن قرار گرفته و ارتباط با اسناد از طریق آنها انجام می‌پذیرد. پس در اینجا قبل از هر کاری باید یک collection را ایجاد کرد و در صورتیکه کالکشن درخواستی وجود نداشته باشد، آن را تولید و ارتباط با آن را برخواهد گرداند.
var collection = db.GetCollection<Book>("books");

در اینجا کالکشنی با نام books با تبدیلاتی بر اساس مدل Book ایجاد میشود. در مرحله بعد لازم است که شیء ایجاد شده بر اساس کلاس مدل را با استفاده از متدهای insert شیء کالکشن، در دیتابیس ارسال کنیم.
شی‌ءهای درج یک سند جدید به دیتابیس حالات مختلفی را دارد: افزودن تک سند، افزودن چند سند و دو مورد قبلی به صورت غیر همزمان میباشند:
collection.InsertOneAsync(book);
متد بالا سند جدید را به صورت غیرهمزمان در سیستم درج میکند. نمونه ذخیره شده این سند را که توسط برنامه Mongo Compass نمایش داده شده است، می‌توانید در زیر ببینید:

فعلا موجودیت‌های مؤلفان و زبان به دلیل اینکه سند اختصاصی برای خود ندارند، با صفر پر شده‌اند؛ ولی شناسه یکتای سند، مقدار خود را گرفته است.


عملیات خواندن

برای خواندن یک یا چند سند از دیتابیس میتوانید از دو شیوه موجود Linq و queryBuilder‌ها استفاده کرد. از آنجائیکه با کار با Linq آشنایی داریم، ابتدای شیوه کوئری بیلدر را مورد بررسی قرار میدهیم و سپس نحوه کار با لینک را بررسی میکنیم.
قبل از هر چیزی برای اینکه در مانور دادن بر روی داده‌ها راحت باشیم و اطلاعات را با فیلترهای متفاوتی واکشی کنیم، 7 عدد کتاب را با مشخصات زیر اضافه میکنیم. دو فیلد سال و تاریخ آخرین موجودی انبار را هم اضافه می‌کنیم.
       var client = new MongoClient();
            var db = client.GetDatabase("publisher");
            db.DropCollection("books");
            var collection = db.GetCollection<Book>("books");
            
            var book =new Book()
           {
               Title = "Gone With Wind",
               ISBN = "43442424",
               Price = 50000,
               Year = 1936,
               LastStock = DateTime.Now.AddDays(-13),
               Language = new Language()
               {
                  Name = "Persian"
               },
               Authors = new List<Author>()
               {
                   new Author()
                   {
                       Name = "Margaret Mitchell"
                   },
                     new Author()
                   {
                       Name = "Ali Mahboobi (Translator)"
                   },
               }
           };

            var book2 = new Book()
            {
                Title = "Jane Eyre",
                ISBN = "87897897",
                Price = 60000,
                Year = 1847,
                LastStock = DateTime.Now.AddDays(-5),
                Language = new Language()
                {
                    Name = "English"
                },
                Authors = new List<Author>()
               {
                   new Author()
                   {
                       Name = "Charlotte Brontë"
                   },
                   
               }
            };


            var book3 = new Book()
            {
                Title = "White Fang",
                ISBN = "43442424",
                Price = 50000,
                Year = 1936,
                LastStock = DateTime.Now.AddDays(-13),
                Language = new Language()
                {
                    Name = "English"
                },
                Authors = new List<Author>()
               {
                   new Author()
                   {
                       Name = "Jack London"
                   },
                     new Author()
                   {
                       Name = "Philippe Mignon"
                   },
               }
            };

            var book4 = new Book()
            {
                Title = "The Lost Symbol",
                ISBN = "43442424",
                Price = 3500000,
                Year = 2009,
                LastStock = DateTime.Now.AddDays(-17),
                Language = new Language()
                {
                    Name = "Persian"
                },
                Authors = new List<Author>()
               {
                   new Author()
                   {
                       Name = "Dan Brown"
                   },
                     new Author()
                   {
                       Name = "Mehrdad"
                   },
               }
            };

            var book7 = new Book()
            {
                Title = "The Lost Symbol",
                ISBN = "43442424",
                Price = 47000000,
                Year = 2009,
                LastStock = DateTime.Now.AddDays(-56),
                Language = new Language()
                {
                    Name = "Persian"
                },
                Authors = new List<Author>()
               {
                   new Author()
                   {
                       Name = "Dan Brown"
                   },
                     new Author()
                   {
                       Name = "Mehrdad"
                   },
               }
            };
            var book5= new Book()
            {
                Title = "The Help",
                ISBN = "45345e3er3",
                Price = 9000000,
                Year = 2009,
                LastStock = DateTime.Now.AddDays(-2),
                Language = new Language()
                {
                    Name = "Enlish"
                },
                Authors = new List<Author>()
               {
                   new Author()
                   {
                       Name = "Kathryn Stockett"
                   },
                    
               }
            };

            var book6 = new Book()
            {
                Title = "City of Glass",
                ISBN = "454534545",
                Price = 500000,
                Year = 2009,
                LastStock = DateTime.Now,
                Language = new Language()
                {
                    Name = "Persian"
                },
                Authors = new List<Author>()
               {
                   new Author()
                   {
                       Name = "Cassandra Clare"
                   },
                   new Author()
                   {
                       Name = "Ali"
                   },

               }
            };
            var books = new List<Book> {book, book2, book3, book4, book5, book6,book7};

            collection.InsertManyAsync(books);

برای واکشی دیتاها کالکشنی از آن نوع را همانند قبل درخواست می‌کنیم. بعد از آن نیاز است که فیلتری برای واکشی اطلاعات تعریف کنیم که این فیلتر در قالب یک کلاس به نام BsonDocument ایجاد می‌شود که ما در اینجا، به دلیل اینکه میخواهیم همه اسناد را واکشی کنیم ، این سند Bson را مقداردهی نمیکنیم و توسط متد Find آن را در واکشی دیتاها شرکت میدهیم و سپس با صدا زدن متد ToList، عملیات واکشی را انجام میدهیم، برای اینکار می‌توانیم از عملیات غیرهمزمان هم استفاده کنیم.
            var client = new MongoClient();
            var db = client.GetDatabase("publisher");
            var collection = db.GetCollection<Book>("books");
            
            var filter=new BsonDocument();
            var docs = collection.Find(filter).ToList();
            foreach (var book in docs)
            {
                Console.WriteLine(book.Title + " By "+ book.Authors[0].Name);
            }

با اجرای کد بالا به نتایج زیر میرسیم:
Gone With Wind By Margaret Mitchell
Jane Eyre By Charlotte Brontë
White Fang By Jack London
The Lost Symbol By Dan Brown
The Help By Kathryn Stockett
City of Glass By Cassandra Clare
The Lost Symbol By Dan Brown

اگر بخواهید فیلتری را بر روی این واکشی قرار دهید و مثلا بخواهید کتاب‌های منتشر شده در سال 2009 را واکشی نمایید، باید این سند Bson را مقداردهی نمایید. ولی برای راحتی اینکار، این  کتابخانه شامل یک بیلدر Builder بوده که میتوان از طریق آن فیلترهای متنوعی را به صورت ساده‌تر طراحی کنید:

در خطوط بالا ابتدا یک بیلدر را برای کلاس مورد نظر ایجاد کرده و از خصوصیت Filter آن استفاده میکنیم و این خصوصیت شامل متدهای فراوانی است که میتوانید برای ایجاد شرط یا فیلتر استفاده کنید. تعدادی از متدهای پر استفاده آن همانند eq (برابری) ، gt (برزگتر از ...) ، gte (بزرگتر مساوی ...) و طبیعتا خانواده lt و ... موجود هستند.
var filter = Builders<Book>.Filter.Eq("Year", 2009);

            var docs = collection.Find(filter).ToList();
            foreach (var book in docs)
            {
                Console.WriteLine(book.Title + " By "+ book.Authors[0].Name);
            }
در کد بالا ما از متد eq برای بررسی برابر بودن استفاده کردیم و درخواست اسنادی را کردیم که دارای فیلد سال انتشار هستند و مقدار آن برابر 2009 میباشد و نتیجه آن به صورت زیر نمایش داده میشود:
The Lost Symbol By Dan Brown
The Help By Kathryn Stockett
City of Glass By Cassandra Clare
The Lost Symbol By Dan Brown
حتی می‌توانید با استفاده از شیء فیلتر، ترکیبات شرطی زیر را نیز اعمال نمایید:
   // var filter=new BsonDocument();
            var filterBuilder = Builders<Book>.Filter;
            var filter= filterBuilder.Eq("Year", 2009) | filterBuilder.Gte("Price",700000);

            var docs = collection.Find(filter).ToList();
            foreach (var book in docs)
            {
                Console.WriteLine(book.Title + " By "+ book.Authors[0].Name);
            }
در بالا ابتدا نوعی از شیء Filter را از کلاس Builder دریافت میکنیم و سپس با استفاده عملیات بیتی آن‌ها را با یکدیگر Or میکنیم. در این پرس و جو باید کتابهایی که در سال 2009 منتشر شده‌اند یا قیمتی کمتر از پنجاه هزار ریال یا برابر را دارند، نمایش داده شوند.

Gone With Wind By Margaret Mitchell
White Fang By Jack London
The Lost Symbol By Dan Brown
The Help By Kathryn Stockett
City of Glass By Cassandra Clare
The Lost Symbol By Dan Brown

برای اینکه بتوانید از linq به جای queryBuilder استفاده کنید، میتوانید از خصوصیت AsQueryable استفاده کنید. خط زیر همان شرط یا فیلتر بالا را توسط Linq اعمال میکند
var docs = collection.AsQueryable().Where(x => x.Year == 2009 || x.Price <= 50000).ToList();

Sort کردن داده‌ها
 
برای مرتب سازی اطلاعات به شیوه کوئری بیلدر، همانند فیلتر که از کلاس Builder استفاده میکردیم، از همین شیء استفاده میکنیم؛ با این تفاوت که بجای استفاده از خصوصیت Filter، از Sort استفاده میکنیم و شیء ایجاد شده را به متد Sort میدهیم:
  var sort = Builders<Book>.Sort.Ascending("Title").Descending("Price");
            var docs = collection.Find(filter).Sort(sort).ToList();
            foreach (var book in docs)
            {
                Console.WriteLine(book.Title + " By "+ book.Authors[0].Name);
            }
در نتیجه خطوط بالا کتاب‌ها ابتدا بر اساس نام به صورت صعودی و سپس بر اساس قیمت به صورت نزولی لیست می‌شوند.
City of Glass By Cassandra Clare
Gone With Wind By Margaret Mitchell
The Help By Kathryn Stockett
The Lost Symbol By Dan Brown
The Lost Symbol By Dan Brown
White Fang By Jack London

توجه داشته باشید که متد sort بعد از فیلتر گذاری، یعنی عمل Find در دسترس میباشد.

در قسمت بعدی به روزرسانی، حذف و ایندکس گذاری را مورد بررسی قرار می‌دهیم.
نظرات مطالب
سفارشی سازی عناصر صفحات پویای افزودن و ویرایش رکوردهای jqGrid در ASP.NET MVC
با تشکر
منظور امکان افزودن بود. یعنی وقتی دکمه افزودن رو میزنه یک سطر جدید واشه توگرید همونجا بنویسه مشکل اصلی من با jTable هم همینه و این یک مورد خیلی مهمه برا کاربرا که نخواد برا افزودن فرم مودال واشه براش.
مثلا من صفحه‌ی MVC دارم که کاربر محصولات و خدماتشو وارد می‌کنه و مدیریت. موردی که هست ممکن کالاهای هر صاحب شغلی حداقل حدود 1000 و به بالا است. و برای ورود اولی خیلی اذیت میشه و ممکن نیست. اگر این افروزنه هم داشته باشه و معرفی کنید ممنون میشم
در هر صورت بازم ازتون تشکر می‌کنم
پاسخ به بازخورد‌های پروژه‌ها
درخواست ایده برای برای پیاده سازی منوی چند سطحی
با همین یک جدول خود ارجاع هم میشه همین کار را کرد.
میشه به صورت ترکیبی از SQL Antipattern شمارش مسیر در کنار این جدول خود ارجاع استفاده کرد به این شکل هم ساختار درختی را دارین هم با توجه به عمق محدود گروه بندی‌ها ، روش شمارش مسیر هم برای کوئری‌ها مربوط به درخت خیلی مفید خواهد بود. 
همچنین در رابطه با بحث جدیدی که مطرح کردید هم میتوانید هنگام درج کالایی ، گروه‌های سطح آخر را اجازه انتخاب دهید. و حالا در سطح اول هم  با امکان شمارش مسیری که گذاشته ایم ، مثلا خیلی راحت پرفروش‌ترین کالاهای آن را  که در شاخه‌های زیرین ثبت شده اند بدست آورد.
این مورد محدود کردن به انتخاب گروه‌های موجود در شاخه  در هنگام درج یکسری  خصوصیات داینامیک (Specification Attribute)  در سیستم باید در سمت برنامه کنترل شود .
نظرات نظرسنجی‌ها
برای نگهداری لیست کارهای روزمره بیشتر از ابزارهای دیجیتال(Excel, Evernote, ..) استفاده میکنید و یا فیزیکی(دفترچه، تخته و...)؟
نظرسنجی جالبیه برای یک توسعه دهنده.
کلا از مصرف گرایی خوشم نمیاد و 80 درصد کارهای یک پروژه را روی سیستم‌های دیجیتالی انجام میدهم و عمدتا از سیستم‌های مدیریت پروژه انلاین ( Trello) استفاده میکنم.
حتی زمانی که مجبور به استفاده از کاغذ یا دفترچه باشم فقط از چک پرینت‌های موجود در دفتر و برای نوشتن از مداد استفاده میکنم.
استفاده از سیستم‌های دیجیتال هم به صرفه تره هم امن تره! اما به گفته دوستمان، لذت استفاده از دفترچه و برگه‌های یادداشت فیزیکی به یادماندنی‌تر است!
پاسخ به بازخورد‌های پروژه‌ها
راهنمایی در مورد سفارش و جزییات سفارش و اتصال به درگاه بانک
شما اگر قبل از هدایت کاربر به سمت درگاه پرداخت ، سفارش کاربر رو ثبت کنید و وضعیت سفارش رو "در انتظار پرداخت " قرار دهید ، می‌توانید کد اصلی جدول پرداخت رو (OrderMaster)  رو به عنوان شماره منحصر بفرد به درگاه پرداخت بفرستید .
بازخوردهای پروژه‌ها
راهنمایی در مورد تحلیل محصول و قیمت
سلام . تشکر بابت پروژه هایی که منتشر می‌کنید .
آقای ربال ، ببینید در مورد محصول و قیمت درست متوجه شدم ؟
یک رابطه یک به چند بین محصول و قیمت وجود دارد که یکی از مزیت‌های این میتونه نمودار بالا پایین تغییرات قیمت محصول باشه . آیا آخرین قیمت رو شما در جدول Product ذخیره میکنید ؟ به نظر شما بهتر است در جدول Product ذخیره شود و یا در جدول Price ؟
ممنون
نظرات مطالب
مدل EAV چیست؟
روش مفید و موثری است. ولی نمی‌دانم با داده‌های حجم بالا هم می‌توان خوب کار کند یا نه. علاوه بر این روش‌های متعارف query روی دیتابیس را به چالش می‌کشد. به عنوان مثال دیگر نمی‌توان با یک Query معمولی فهرست کالاها و مشخصات و گروه بندی بر اساس فلان Attribute را استخراج کرد.