آشنایی با Gridify
CheckBoxList در ASP.NET MVC
زحمات بسیاری در رابطه با آموزش کشیدید متشکر. امکانش هست که مثالی از نحوه فراخوانی اطلاعات از دیتابیس بوسیله Entity Framework در mvc نیز بیاورید
متشکرم
- ضمنا یک Visual NHibernate تجاری هم موجود است:
Visual NHibernate
using System.Data.Entity.Core.Metadata.Edm;
public class SoftDeleteAttribute : Attribute { public string ColumnName { get; set; } public SoftDeleteAttribute(string column) { ColumnName = column; } public static string GetSoftDeleteColumnName(EdmType type) { MetadataProperty column = type.MetadataProperties.Where(x => x.Name.EndsWith("customannotation:SoftDeleteColumnName")).SingleOrDefault(); return column == null ? null : (string)column.Value; } }
سؤال: متادیتای "customannotation:SoftDeleteColumnName" از کجا آمد؟ برای پاسخ به این سوال کافیست ادامهی مطلب را کامل مطالعه نمایید.
[SoftDelete("IsDeleted")] public class TblUser { [Key] public int TblUserID { get; set; } [MaxLength(30)] public string Name { get; set; } public bool IsDeleted { get; set; } }
protected override void OnModelCreating(DbModelBuilder modelBuilder) { var Conv = new AttributeToTableAnnotationConvention<SoftDeleteAttribute, string>( "SoftDeleteColumnName", (type, attribute) => attribute.Single().ColumnName); modelBuilder.Conventions.Add(Conv); }
در پنجره باز شده به قسمت سوم یعنی <StorageModels> مراجعه نمایید و بایستی گزینه زیر را مشاهده نمایید .
<EntityType Name="TblUser" customannotation:SoftDeleteColumnName="IsDeleted">
تا اینجای کار ما توانستیم یک Annotation جدید را به Ef اضافه نماییم .
در مرحله بعد بایستی به Ef دستور دهیم که در تولید Query بر روی این Entity، این مورد را نیز لحاظ کند.
برای این کار کلاسی را ایجاد مینماییم که از اینترفیس IDbCommandTreeInterceptor ارث بری مینماید. مانند کد زیر :
public class SoftDeleteInterceptor : IDbCommandTreeInterceptor { public void TreeCreated(DbCommandTreeInterceptionContext interceptionContext) { if (interceptionContext.OriginalResult.DataSpace == System.Data.Entity.Core.Metadata.Edm.DataSpace.SSpace) { var QueryCommand = interceptionContext.Result as DbQueryCommandTree; if (QueryCommand != null) { var newQuery = QueryCommand.Query.Accept(new SoftDeleteQueryVisitor()); interceptionContext.Result = new DbQueryCommandTree(QueryCommand.MetadataWorkspace, QueryCommand.DataSpace, newQuery); } } } }
در ابتدا تشخیص داده میشود که نوع خروجی Query آیا از نوع Storage Model است . ( برای توضیحات بیشتر ) سپس پرس و جوی تولید شده را با استفاده از الگوی visitor تغییر داده و Query جدید را تولید نموده و در انتها Query جدیدی را به جای Query قبلی جایگزین مینماییم.
در اینجا ما نیاز به داشتن کلاس SoftDeleteQueryVisitor برای تغییر دادن Query و اضافه نمودن IsDeleted <>1 به Query میباشیم.
یک کلاس دیگری با نام SoftDeleteQueryVisitor به شکل زیر به برنامه اضافه مینماییم.
public class SoftDeleteQueryVisitor : DefaultExpressionVisitor { public override DbExpression Visit(DbScanExpression expression) { var column = SoftDeleteAttribute.GetSoftDeleteColumnName(expression.Target.ElementType); if (column!=null) { var Binding = DbExpressionBuilder.Bind(expression); return DbExpressionBuilder.Filter(Binding, DbExpressionBuilder.NotEqual(DbExpressionBuilder.Property(DbExpressionBuilder.Variable(Binding.VariableType, Binding.VariableName), column), DbExpression.FromBoolean(true))); } else { return base.Visit(expression); } } }
در نهایت برای اینکه EF تشخیص دهد که یکچنین Interceptor ایی وجود دارد، بایستی در کلاس DbContextConfig، کلاس SoftDeleteInterceptor را اضافه نماییم؛ همانند کد زیر:
public class DbContextConfig : DbConfiguration { public DbContextConfig() { AddInterceptor(new SoftDeleteInterceptor()); } }
تا اینجا در تمام Queryهای تولید شده بر روی Entity که با خاصیت SoftDelete مزین شده است، مقدار IsDeleted <> 1 را به صورت اتوماتیک اعمال مینماید. حتی به صورت هوشمند چنانچه این موجودیت در یک Join استفاده شده باشد این شرط را قبل از Join به Query تولید شده اضافه مینماید.
در مقاله بعدی در مورد تغییر کد Remove به کد Update توضیح داده خواهد شد.
برای مطالعه بیشتر
Entity Framework: Building Applications with Entity Framework 6
- برای حالت database first نیاز به VS 2013 دارید تا از کلیه امکانات EF 6 استفاده کنید (یا باید به روز رسانی خاصی را برای VS 2012 نصب کنید). حالت Code first مستقل است از IDE (یک مزیت دیگر).
Entity Framework Designer همراه با VS 2012 فقط از EF 5 پشتیبانی میکند (در حالت پیش فرض) و از تغییرات انجام شده در EF 6 آگاه نیست. به همین جهت اگر با VS 2012 بخواهید با EF6 کار کنید (در حالت database first) باز هم همان اسمبلی قدیمی System.Data.Entity.dll را مورد استفاده قرار میدهد که در EF 6 اصلا کاربردی ندارد و با آن یکی شده است.
البته در کل میتونید با VS 2012 هم در حالت database first با EF 6 کار کنید ولی نیاز به یک سری تغییرات دستی خواهید داشت (EF قدیمی و همچنین اسمبلی اضافی یاد شده را باید دستی حذف کنید) و به علاوه از بهبودهای جدید آن (در حالت پیش فرض و بدون به روز رسانی) محروم خواهید بود.
Entity Framework Designer سورس باز نیست (برخلاف هسته EF) و جزئی از VS.NET است. قرار است در آینده این افزونه را هم سورس باز کنند تا بتوانند مستقل از چرخه طول عمر VS.NET، خود EF Database first را نیز به روز کنند.
ولی در کل اگر از Code first استفاده میکنید، EF6 حتی با VS 2010 هم سازگار است.
- زمانیکه با یک ORM کار میکنید (فرقی نمیکند به چه اسمی)، لایه DAL همان ORM هست. (دست به اختراع لایههای اضافی نزنید)