میخوام لیست گروهبندی مطالبمو تو _Layout.cshtml ( نمایش در تمام صفحات مثل MasterPage در WebForm) نشون بدم چه راهی رو پیشنهاد میدید ؟ خیلی ممنون
میخوام لیست گروهبندی مطالبمو تو _Layout.cshtml ( نمایش در تمام صفحات مثل MasterPage در WebForm) نشون بدم چه راهی رو پیشنهاد میدید ؟ خیلی ممنون
public void Init(HttpApplication application) { application.EndRequest += onEndRequest; } public void onEndRequest(Object sender, EventArgs e) { HttpCookieCollection cookies = (((HttpApplication)sender).Response).Cookies; //todo: check Cookie.Value.Length
public class ProductModel { public ProductModel(IContextAccessor<ActionContext> action, IProductService prodService) { //TODO: Do some error checking... var productId = action.Value.RouteData.Values["product"]; Value = prodService.Get(productId); } public IProduct Value { get; private set; } }
foreach (string file in Request.Files) { var hpf = Request.Files[file] as HttpPostedFileBase; // todo: save it }
public async override Task<IList<string>> GetRolesAsync(Guid userId) { var userPermissions = await _roleManager.FindUserPermissions(userId); ////todo: any permission form other sections return userPermissions; }
public override void OnActionExecuted(ActionExecutedContext filterContext) { if (LogType == AuditLogType.Login) { AuditLogService.Create(Description, LogType); } if (LogType != AuditLogType.Serialize) return; if (filterContext.Controller.ViewData.ModelState.IsValid) { AuditLogService.Create(Description, LogType); } base.OnActionExecuted(filterContext); }
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; } }
[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