قبل از اینکه این موضوع را بررسی کنیم باید با دستور Truncate و Delete آشنا شویم.
DELETE FROM table_name WHERE some_column=some_value
DELETE FROM Customers WHERE Country=’USA’ GO
اما نکته مهمی که دستور Delete دارد این است کار این دستور به شکل Transactional میباشد. یعنی یا کلیه رکوردهایی که Country آنها USA است حذف میشود و یا هیچکدام از آنها. پس اگر شما 200000 رکورد داشته باشید که در این شرط صدق کند اگر وسط کار Delete (البته اگر عملیات حذف طولانی باشد) منصرف شوید میتوانید با Cancel کردن این دستور عملیات Rollback Transaction را به خودکار توسط SQL Server داشته باشید. در صورتیکه عملیات Cancel را انجام دهید SQL Server از Log File برای بازگرداندن مقادیر حذف شده استفاده خواهد کرد.
شکل کلی استفاده از این دستور به صورت زیر میباشد.
TRUNCATE TABLE table_name GO
TRUNCATE TABLE Customers GO
2- دستور Truncate Table در Log File آدرس Page و مقدار فضای آزاد شده (کمترین میزان Log) را مینویسد اما در صورتیکه دستور Delete در Log هر رکوردی را که
قرار است حذف شود را در Log File ثبت مینماید.
3- دستور Truncate Table باعث میشود که Pageهای متعلق به جدول deallocate شوند. deallocate شدن Pageها این معنی را میدهد که رکوردهای موجود در جدول واقعاً حذف نشوند بلکه Extentهای مربوط به آن Pageها علامت Empty خورده تا دفعات بعد مورد استفاده قرار گیرند اما دستور Delete به طور فیزیکی محتوای Pageها مربوط به جدول را خالی میکند.
نکته : پس از Truncate شدن رکوردها امکان بازگشت آنها وجود ندارد.
4- در صورتیکه جدول شما دارای ایندکس باشد. دستور Truncate Table آزاد کردن فضای مربوط به ایندکس را در یک مرحله انجام میدهد(مطابق بند 3) همچنین Log مربوط به این حذف به شکل حداقل (مطابق بند 2) در Log File ثبت میشود. اما دستور Delete هر رکوردی را که از ایندکس حذف میکند در Log File ثبت میکند.
5- Trigger مربوط به دستور Delete به هیچ عنوان هنگام اجرای دستور Truncate Table فعال نمیشود. در صورتیکه با اجرای دستور Delete تریگر آن فعال خواهد شد.
6- در صورتیکه جدول شما دارایRelation) Reference) باشد امکان استفاده از دستور Truncate Table وجود ندارد. لازم به ذکر است حتی اگر Reference را غیر فعال کنید
باز هم امکان استفاده از دستور Truncate Table وجود نخواهد داشت و تلاش برای اجرای دستور Truncate Table باعث نمایش خطای زیر خواهد شد.
در صورتیکه در دستور Delete امکان حذف رکوردها به ازای جداولی که دارای Relation هستند وجود دارد. فقط باید به این نکته توجه کنید که ترتیب حذف رکوردها از جداول Master و Detail را رعایت کنید.
7- دستور Truncate Table مقدار Identity را Reset کرده و آن را به Seed (هسته/مقدار اولیه) بر میگرداند. در صورتیکه دستور Delete تاثیری بر روی مقدار Identity ندارد
8- دستور Truncate Table تنها توسط کاربرانی قابل اجرا است که نقش DB_Owner و یا SysAdmin را داشته باشند در صورتیکه دستور Delete توسط هر کاربری که مجوز Delete بر روی جدول را داشته باشد قابل اجرا میباشد.
9- پس از اجرای دستور Truncate Table تعداد رکوردهای حذف شده نمایش داده نمیشود. در صورتیکه هنگام اجرای دستور Delete تعداد رکوردهای حذف شده نمایش داده میشود.
An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key
T attachedEntity = set.Find(entity.Id); var attachedEntry = dbContext.Entry(attachedEntity); attachedEntry.CurrentValues.SetValues(entity);
public DbContext() { this.Configuration.ProxyCreationEnabled = false; this.Configuration.LazyLoadingEnabled = false; this.Configuration.AutoDetectChangesEnabled = false; }
dbContext.Entry(entity).State = EntityState.Unchanged ; dbContext.Entry(entity).State = EntityState.Added ; //or Dbset.Add(entity) dbContext.Entry(entity).State = EntityState.Modified ; dbContext.Entry(entity).State = EntityState.Deleted ; // or Dbset.Remove(entity)
dbContext.Entry(entity).State = EntityState.Detached;
// group id=19 Name="General" var customer = new Customer(); customer.Group = group; customer.Name = "mohammadi"; dbContext.Entry(customer).State = EntityState.Added; var customerstate = dbContext.Entry(customer).State;// customerstate=EntityState.Added var groupstate = dbContext.Entry(group);// groupstate=EntityState.Added
// group id=19 Name="General" var customer = new Customer(); customer.Group = group; customer.Name = "mohammadi"; dbContext.Entry(group).State = EntityState.Unchanged; dbContext.Entry(customer).State = EntityState.Added; var customerstate = dbContext.Entry(customer).State;// customerstate=EntityState.Added var groupstate = dbContext.Entry(group);// groupstate=EntityState.Unchanged
// group id=19 Name="General" var customer = new Customer(); customer.Group = group; customer.Name = "mohammadi"; dbContext.Entry(customer).State = EntityState.Unchanged; dbContext.Entry(customer).State = EntityState.Added; var customerstate = dbContext.Entry(customer).State;// customerstate=EntityState.Added var groupstate = dbContext.Entry(group);//// groupstate=EntityState.Unchanged
var customer = dbContext.Customers.FirstOrDefault(); var customerAsNoTracking = dbContext.Customers.AsNoTracking().FirstOrDefault(); var customerstate = dbContext.Entry(customer).State;// customerstate=EntityState.Unchanged var customerstateAsNoTracking = dbContext.Entry(customerAsNoTracking).State;// customerstate=EntityState.Detached
var Entries = dbContext.ChangeTracker.Entries(); var AddedEntries = dbContext.ChangeTracker.Entries().Where(entityEntry => entityEntry.State==EntityState.Added); var ModifiedEntries = dbContext.ChangeTracker.Entries().Where(entityEntry => entityEntry.State==EntityState.Modified); var UnchangedEntries = dbContext.ChangeTracker.Entries().Where(entityEntry => entityEntry.State==EntityState.Unchanged); var DeletedEntries = dbContext.ChangeTracker.Entries().Where(entityEntry => entityEntry.State==EntityState.Deleted); var DetachedEntries = dbContext.ChangeTracker.Entries().Where(entityEntry => entityEntry.State==EntityState.Detached);//* not working !
var CustomersWithGroup = dbContext.Customers.AsNoTracking().Include("Group").ToList(); var CustomerFull = dbContext.Customers.AsNoTracking().Include("Group").Include("Bills").Include("Bills.BillDetails").ToList();
public virtual void AddOrUpdate(T entity) { if (entity.Id == 0) Add(entity); else Update(entity); }
5) اگر بخواهیم موجودیتهای رابطه ای در دیتا گرید ویو (ویندوز فرم) نشون بدیم باید چه کار کنیم؟
گرید ویو در ویندوز فرم قادر به نشون دادن فیلدهای رابطه ای نیست برای حل این مشکل میتونیم یک نوع ستون جدید برای گرید ویو تعریف کنیم و برای نشون دادن فیلدهای رابطه ای از این نوع ستون استفاده کنیم:
public class DataGridViewChildRelationTextBoxCell : DataGridViewTextBoxCell { protected override object GetValue(int rowIndex) { try { var bs = (BindingSource)DataGridView.DataSource; var cl = (DataGridViewChildRelationTextBoxColumn)DataGridView.Columns[ColumnIndex]; return getChildValue(bs.List[rowIndex], cl.DataPropertyName).ToString(); } catch (Exception) { return ""; } } private object getChildValue(object dataSource, string childMember) { int nextPoint = childMember.IndexOf('.'); if (nextPoint == -1) return dataSource.GetType().GetProperty(childMember).GetValue(dataSource, null); string proName = childMember.Substring(0, nextPoint); object newDs = dataSource.GetType().GetProperty(proName).GetValue(dataSource, null); return getChildValue(newDs, childMember.Substring(nextPoint + 1)); } } public class DataGridViewChildRelationTextBoxColumn : DataGridViewTextBoxColumn { public string DataMember { get; set; } public DataGridViewChildRelationTextBoxColumn() { CellTemplate = new DataGridViewChildRelationTextBoxCell(); } }
نحوه استفاده را در ادامه میبینید. این روش توسط ویزارد گریدویو هم قابل استفاده است. موقع Add کردن Column نوع اون رو روی DataGridViewChildRelationTextBoxColumn تنظیم کنید.
GroupNameColumn= new DataGridViewChildRelationTextBoxColumn(); //from your class GroupNameColumn.HeaderText = "گروه مشتری"; GroupNameColumn.DataPropertyName = "Group.Name"; //EF Property: Customer.Group.Name GroupNameColumn.Visible = true; GroupNameColumn.Width = 300; DataGridView.Columns.Add(GroupNameColumn);
ساختار مورد نیاز یک Kendo UI Tree View
فرض کنید قصد دارید نظرات تو در توی مطلبی را توسط Kendo UI Tree View نمایش دهید. مدل خود ارجاع دهندهی آن میتواند چنین شکلی را داشته باشد:
namespace KendoUI11.Models { public class BlogComment { public int Id { set; get; } public string Body { set; get; } public int? ParentId { get; set; } // مخصوص کندو یو آی هستند public bool HasChildren { get; set; } public string imageUrl { get; set; } } }
چند خاصیت بعدی مانند HasChildren و imageUrl مخصوص Kendo UI هستند. از imageUrl اختیاری میتوان جهت نمایش آیکنی در کنار یک آیتم استفاده کرد و HasChildren به این معنا است که آیا گره جاری دارای عناصر فرزندی میباشد یا خیر.
تهیه یک منبع داده نمونه
شکل ابتدای مطلب، از طریق منبع داده ذیل تهیه شدهاست:
using System.Collections.Generic; namespace KendoUI11.Models { /// <summary> /// منبع داده فرضی جهت سهولت دموی برنامه /// </summary> public static class BlogCommentsDataSource { private static readonly IList<BlogComment> _cachedItems; static BlogCommentsDataSource() { _cachedItems = createBlogCommentsDataSource(); } public static IList<BlogComment> LatestComments { get { return _cachedItems; } } /// <summary> /// هدف صرفا تهیه یک منبع داده آزمایشی ساده تشکیل شده در حافظه است /// </summary> private static IList<BlogComment> createBlogCommentsDataSource() { var list = new List<BlogComment>(); var comment1 = new BlogComment { Id = 1, Body = "نظر من این است که", HasChildren = true, ParentId = null }; list.Add(comment1); var comment12 = new BlogComment { Id = 2, Body = "پاسخی به نظر اول", HasChildren = true, ParentId = 1 }; list.Add(comment12); var comment12A = new BlogComment { Id = 3, Body = "پاسخی دیگری به نظر اول", HasChildren = false, ParentId = 1 }; list.Add(comment12A); var comment121 = new BlogComment { Id = 4, Body = "پاسخی به پاسخ به نظر اول", HasChildren = false, ParentId = 2 }; list.Add(comment121); var comment2 = new BlogComment { Id = 5, Body = "نظر 2", HasChildren = true, ParentId = null, imageUrl= "images/search.png" }; list.Add(comment2); var comment21 = new BlogComment { Id = 6, Body = "پاسخ به نظر 2", HasChildren = false, ParentId = 5 }; list.Add(comment21); return list; } } }
در این لیست دو رکورد، دارای ParentId مساوی null هستند. از این null بودنها جهت کوئری گرفتن و نمایش ریشههای TreeView در ادامه استفاده خواهیم کرد.
بازگشت نظرات با فرمت JSON به سمت کلاینت
در ادامه یک کنترلر ASP.NET MVC را مشاهده میکنید که توسط اکشن متد GetBlogComments، رکوردهای مورد نظر را با فرمت JSON به سمت کلاینت ارسال میکند:
using System.Linq; using System.Web.Mvc; using KendoUI11.Models; namespace KendoUI11.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(); // shows the page. } [HttpGet] public ActionResult GetBlogComments(int? id) { if (id == null) { //دریافت ریشهها return Json( BlogCommentsDataSource.LatestComments .Where(x => x.ParentId == null) // ریشهها .ToList(), JsonRequestBehavior.AllowGet); } else { //دریافت فرزندهای یک ریشه return Json( BlogCommentsDataSource.LatestComments .Where(x => x.ParentId == id) .ToList(), JsonRequestBehavior.AllowGet); } } } }
اگر مقدار id به سمت سرور ارسال شود، یعنی کاربر گره و نودی را گشودهاست. بر این اساس، تمامی فرزندان این گره را یافته و بازگشت میدهیم.
کدهای سمت کاربر نمایش Kendo UI Tree View
برای کار با Kendo UI TreeView نیاز است از منبع داده خاصی به نام HierarchicalDataSource به نحو ذیل استفاده کنیم. در قسمت transport آن مشخص میکنیم که اطلاعات باید از چه آدرسی خوانده شوند که در اینجا به آدرس اکشن متد GetBlogComments اشاره میکند.
همچنین نیاز است مشخص کنیم کدامیک از خواص مدل بازگردانده شده، همان hasChildren است که در مثال فوق دقیقا به همین نام نیز تنظیم شدهاست.
<!--نحوهی راست به چپ سازی --> <div class="k-rtl k-header demo-section"> <div id="my-treeview"></div> </div> @section JavaScript { <script type="text/javascript"> $(function () { var dataSource = new kendo.data.HierarchicalDataSource({ transport: { read: { url: "@Url.Action("GetBlogComments", "Home")", dataType: "json", contentType: 'application/json; charset=utf-8', type: 'GET' } }, schema: { model: { id: "Id", hasChildren: "HasChildren" } } }); $("#my-treeview").kendoTreeView({ //استفاده از قالب در صورت نیاز template: kendo.template($("#treeview-template").html()), checkboxes: { checkChildren: false }, dataSource: dataSource, dataTextField: "Body", //رخدادها select: function (e) { console.log("Selecting: " + this.text(e.node)); }, check: function (e) { console.log("Checkbox changed :: " + this.text(e.node)); }, change: function (e) { console.log("Selection changed"); }, collapse: function (e) { console.log("Collapsing " + this.text(e.node)); }, expand: function (e) { console.log("Expanding " + this.text(e.node)); } }); }); </script> <script id="treeview-template" type="text/kendo-ui-template"> <strong> #: item.Body # </strong> </script> <style scoped> .demo-section { width: 100%; height: 300px; } </style> }
- در ابتدا به ازای هر ردیف این TreeView، از یک قالب استفاده شدهاست. تعریف این مورد اختیاری است. اگر نیاز به سفارشی سازی نحوهی نمایش هر آیتم را داشتید، میتوان از قالبها استفاده کرد.
- قسمت checkboxes مشخص میکند که آیا نیاز است در کنار هر آیتم یک checkbox نیز نمایش داده شود یا خیر.
- dataSource را به HierarchicalDataSource تنظیم کردهایم.
- dataTextField مشخص میکند که کدام فیلد دربرگیرندهی متن هر آیتم TreeView است.
- تعدادی رخداد منتسب به TreeView نیز تنظیم شدهاند که خروجی آنها را در console تصویر ابتدای بحث مشاهده میکنید.
کدهای کامل این مثال را از اینجا میتوانید دریافت کنید.
- Testing with a mocking framework - EF6 onwards
+ شخصا اعتقادی به Unit tests درون حافظهای، در مورد لایه دسترسی به دادهها ندارم. به قسمت «Limitations of EF in-memory test doubles» مراجعه کنید؛ توضیحات خوبی را ارائه دادهاست.
تست درون حافظهی LINQ to Objects با تست واقعی LINQ to Entities که روی یک بانک اطلاعاتی واقعی اجرا میشود، الزاما نتایج یکسانی نخواهد داشت (به دلیل انواع قیود بانک اطلاعاتی، پشتیبانی از SQL خاص تولید شده تا بارگذاری اشیاء مرتبط و غیره) و نتایج مثبت آن به معنای درست کار کردن برنامه در دنیای واقعی نخواهد بود. در اینجا Integration tests بهتر جواب میدهند و نه Unit tests.
- اصل Interface Segregation چیست؟ | www.dotnetdev.info
- چند نکته در مورد فیلد Identity در SQL | vsblogger.blogfa.com
- گوگل سالانه 300 میلیون دلار به موزیلا پرداخت می کند | www.winbeta.net
- وزیر ارتباطات : دسترسی به اینترنت ممکن است حذف شود | www.winbeta.net
- FIXED – 64-bit Adobe PDF Previewer | www.sharepointjohn.com
- LINQ Extensions Library | linqlib.codeplex.com
- Reactive Extensions (Rx) v1.0.10621 SP1 | www.microsoft.com
- Return-Oriented Programming | cseweb.ucsd.edu
- 11 کاری که هر برنامه نویس بهتر است در سال 2012 انجام دهد | michaelcrump.net
- Max & Min in LINQ to XML | rmanimaran.wordpress.com
- سه پروژه آغازین با Roslyn | www.codeproject.com
- مروری بر مباحث امنیتی سیلورلایت 5 | blogs.msdn.com
خطای sql ؟
- Power Shell Command Builder | pspcommunity.org
- فایرفاکس 8 فردا معرفی می شود، امکان دانلود از امروز « WinBeta.Net | Where Tech Becomes Life | www.winbeta.net
- وبینار و پادکست آزاد و رایگان Agile | دنیای چابک | blog.irscrum.com
- New SQL Server 2012 Labs and Presentations | blogs.msdn.com
- اضافه کردن Watermark به PDF تولیدی توسط iTextSharp | footheory.com
- دریافت کتاب رایگان Windows Phone Blue Book | www.robmiles.com
- لیست موارد منسوخ شده در SQL Server | technet.microsoft.com