paint-brush
ہستی کا فریم ورک 8 - جزوی کلاسز کی ترکیبیں جن کے بارے میں آپ کو معلوم ہونا چاہیے۔کی طرف سے@markpelf
نئی تاریخ

ہستی کا فریم ورک 8 - جزوی کلاسز کی ترکیبیں جن کے بارے میں آپ کو معلوم ہونا چاہیے۔

کی طرف سے Mark Pelf17m2025/02/19
Read on Terminal Reader

بہت لمبا؛ پڑھنے کے لئے

EF 8 میں - ڈیٹا بیس فرسٹ اپروچ میں تیار کردہ EF کلاسز کو اضافی فعالیت کے ساتھ براہ راست نہیں بڑھایا جا سکتا۔ اس پر قابو پانے کے لیے، ہم جزوی C# کلاسز کا فائدہ اٹھا سکتے ہیں۔ یہ مضمون EF/ASP.NET ماحول میں فعالیت کو بڑھانے کے لیے مفید چالیں پیش کرتا ہے۔
featured image - ہستی کا فریم ورک 8 - جزوی کلاسز کی ترکیبیں جن کے بارے میں آپ کو معلوم ہونا چاہیے۔
Mark Pelf HackerNoon profile picture

یہ مضمون EF 8/ASP.NET8 میں عام مسائل کو حل کرنے کے لیے جزوی C# کلاسز استعمال کرنے کے لیے متعدد تکنیکوں کو ظاہر کرتا ہے۔


خلاصہ: EF 8 میں - ڈیٹا بیس فرسٹ اپروچ میں تیار کردہ EF کلاسز کو اضافی فعالیت کے ساتھ براہ راست نہیں بڑھایا جا سکتا ہے کیونکہ جب ماڈل کو دوبارہ تخلیق کیا جاتا ہے تو وہ اوور رائٹ ہو جاتی ہیں۔ اس پر قابو پانے کے لیے، ہم جزوی C# کلاسز کا فائدہ اٹھا سکتے ہیں۔ یہ مضمون EF/ASP.NET ماحول میں فعالیت کو بڑھانے کے لیے مفید چالیں پیش کرتا ہے۔

1 ہستی فریم ورک کور - ڈیٹا بیس پہلا نقطہ نظر

اپنے C#/ASP.NET 8 MVC پروجیکٹ میں، میں Entity Framework Core Database First اپروچ استعمال کر رہا ہوں۔ یہ ضروری ہے کیونکہ مختلف ٹیکنالوجیز میں متعدد ایپلیکیشنز ایک ہی SQL سرور ڈیٹا بیس پر انحصار کرتی ہیں۔ ڈیٹا بیس سے ماڈل بنانے کے لیے، میں EFCorePowerTools استعمال کرتا ہوں۔


مسئلہ اس وقت پیدا ہوتا ہے جب ڈیٹا بیس اسکیما میں تبدیلیوں کی عکاسی کرنے کے لیے تیار کردہ EF ماڈل کو اپ ڈیٹ کرنے کی ضرورت ہوتی ہے۔ چونکہ تیار کردہ EF ہستی کی کلاسیں اوور رائٹ ہو جائیں گی، اس لیے ان میں کی گئی کوئی بھی ترمیم ضائع ہو جاتی ہے۔ یہ ایک مسئلہ ہے کیونکہ، بعض اوقات، ہمیں درخواست کے اندر استعمال کے لیے EF اداروں کو بڑھانے کی ضرورت ہوتی ہے۔


اس مسئلے کو حل کرنے کے لیے، میں جزوی C# کلاسوں پر مشتمل چالوں پر انحصار کرتا ہوں، جن کی وضاحت ذیل میں کی جائے گی۔

2 C#/EF/ASP.NET ایپ میں ایک عام صورتحال

ایک عام C#/EF/ASP.NET 8 MVC ایپلیکیشن میں، صورتحال درج ذیل کوڈ کی طرح نظر آ سکتی ہے:

 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //this is typical class generated by EF Core Power Tools //in EF-Database-First approach // <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated> [PrimaryKey("Id")] public partial class Customer { //Customer-partial-class-1 [Key] [StringLength(15)] public string? Id { get; set; } [StringLength(15)] public string? NAME { get; set; } public short? Language { get; set; } } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //this is typical model calls for ASP.NET MVC public class CustomerEdit_ViewModel { //model public string? Id { get; set; } = null; //view model // this is our Customer Entity from EF Core public Customer? Customer1 { get; set; } = null; //this is flag for submit button public bool IsSubmit { get; set; } = false; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //this is typical controller for ASP.NET MVC public class CustomersController : Controller { // some Controller code here public async Task<ActionResult> CustomerEdit(CustomerEdit_ViewModel model) { if (model.IsSubmit) { // Model validation is done during model binding // we have to check if model is valid if (ModelState.IsValid) { if (model.Customer1 != null) { //we update existing customer in database //redirect to the list of customers } } else { // we go for presentation of validation errors ModelState.AddModelError("", "PleaseCorrectAllErrors"); } } else { ModelState.Clear(); //go for presentation of original data if (model.Id != null) { //get Customer by Id from database } } return View("CustomerEdit", model); } }

یہاں، Customer-partial-class-1 EF (ڈیٹا بیس سے ریورس انجینئرنگ کے ذریعے) کے ذریعے تیار کردہ ایک کلاس ہے۔ اس میں کچھ توثیق کی خصوصیات شامل ہیں جو ڈیٹا بیس کی رکاوٹوں سے مطابقت رکھتی ہیں۔ یہ کلاس عام طور پر ماڈل کلاس میں استعمال ہوتی ہے (مثلاً CustomerEdit_ViewModel )، جہاں توثیق کی صفات پر کارروائی یا طریقہ کار کے دوران عمل کیا جاتا ہے (جیسے CustomerEdit

3 چال 1 - اپنی مرضی کے مطابق پراپرٹیز شامل کرنے کے لیے جزوی کلاسز کا استعمال کریں۔

اگر ہمیں جنریٹڈ کلاس میں پراپرٹیز شامل کرنے کی ضرورت ہے، تو ہم Customer-partial-class-1 میں براہ راست ترمیم نہیں کر سکتے، کیونکہ ایسا کرنے سے تبدیلیاں اوور رائٹ ہو جائیں گی۔ اس کے بجائے، ہم Customer-partial-class-2 بنا سکتے ہیں اور وہاں اپنی حسب ضرورت خصوصیات شامل کر سکتے ہیں۔ EF کو ماڈل میں ان خصوصیات کو شامل کرنے سے روکنے کے لیے، ہمیں [NotMapped] وصف استعمال کرنا چاہیے۔


یہاں ایک مثال ہے:

 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //this is typical class generated by EF Core Power Tools //in EF-Database-First approach // <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated> [PrimaryKey("Id")] public partial class Customer { //Customer-partial-class-1 [Key] [StringLength(15)] public string? Id { get; set; } [StringLength(15)] public string? NAME { get; set; } public short? Language { get; set; } } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //this is our partial class that extends our generated class //and is not overwritten by EF Core Power Tools //we use it to add some additional properties public partial class Customer { //Customer-partial-class-2 [NotMapped] public int NumberOfCreditCards { get; set; } = 0; [NotMapped] public string? LanguageString { get { string? result = "Unknown"; if (Language == 1) { result = "English"; } else if (Language == 2) { result = "German"; } return result; } } } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //this is typical model calls for ASP.NET MVC public class CustomerEdit_ViewModel { //model public string? Id { get; set; } = null; //view model // this is our Customer Entity from EF Core public Customer? Customer1 { get; set; } = null; //this is flag for submit button public bool IsSubmit { get; set; } = false; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //this is typical controller for ASP.NET MVC public class CustomersController : Controller { // some Controller code here //............. //this is typical action for editing customer public async Task<ActionResult> CustomerEdit(CustomerEdit_ViewModel model) { if (model.IsSubmit) { // Model validation is done during model binding // we have to check if model is valid if (ModelState.IsValid) { if (model.Customer1 != null) { //we update existing customer in database //redirect to the list of customers } } else { // we go for presentation of validation errors ModelState.AddModelError("", "PleaseCorrectAllErrors"); } } else { ModelState.Clear(); //go for presentation of original data if (model.Id != null) { //get Customer by Id from database } } return View("CustomerEdit", model); } }

کوڈ، تفصیلی تبصروں کے ساتھ، خود وضاحتی ہونا چاہیے۔

4 چال 2 - اپنی مرضی کے مطابق توثیق کی خصوصیات شامل کرنے کے لیے جزوی کلاسز کا استعمال کریں۔

بعض اوقات، EF میں خود بخود پیدا ہونے والی توثیق کی خصوصیات کافی نہیں ہوتی ہیں، اور ہمیں اپنی مرضی کے مطابق توثیق کے قواعد شامل کرنے کی ضرورت ہوتی ہے۔ ایک بار پھر، جزوی طبقے بچاؤ کے لیے آتے ہیں۔ ذیل میں ایک مثال ہے:

 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //this is typical class generated by EF Core Power Tools //in EF-Database-First approach // <auto-generated> This file has been auto generated by EF Core Power Tools. </auto-generated> [PrimaryKey("Id")] public partial class Customer { //Customer-partial-class-1 [Key] [StringLength(15)] public string? Id { get; set; } [StringLength(15)] public string? NAME { get; set; } public short? Language { get; set; } } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //this is our partial class that extends our generated class //and is not overwritten by EF Core Power Tools //we use it to add some additional properties //and do some additional validation [MetadataType(typeof(Customer_MetaData))] public partial class Customer { //Customer-partial-class-2 public Customer() { TypeDescriptor.AddProviderTransparent( new AssociatedMetadataTypeTypeDescriptionProvider( typeof(Customer), typeof(Customer_MetaData)), typeof(Customer)); } [NotMapped] public int NumberOfCreditCards { get; set; } = 0; [NotMapped] public string? LanguageString { get { string? result = "Unknown"; if (Language == 1) { result = "English"; } else if (Language == 2) { result = "German"; } return result; } } } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //this is our metadata class for our partial class //purpose of this class is to add validation attributes to our partial class //in addition to those that are already in generated class public class Customer_MetaData { //main trick here is that we are adding more validation attributes //in addition to those in generated class [Required] [MinLength(5)] public string? Id { get; set; } = string.Empty; //main trick here is that we are adding more validation attributes //in addition to those in generated class [Required] [MinLength(3)] public string? NAME { get; set; } = string.Empty; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //this is typical model calls for ASP.NET MVC public class CustomerEdit_ViewModel { //model public string? Id { get; set; } = null; //view model // this is our Customer Entity from EF Core public Customer? Customer1 { get; set; } = null; //this is flag for submit button public bool IsSubmit { get; set; } = false; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //this is utility class for validation public class ValidationUtil { /// <summary> /// Validates the specified model object against custom validation rules. /// </summary> /// <param name="model">The model object to validate.</param> /// <param name="modelState">The ModelStateDictionary to store validation errors.</param> /// <param name="logger">The logger to log errors.</param> /// <param name="prefix">An optional prefix for error keys in the ModelStateDictionary.</param> /// <returns>True if validation is successful; otherwise, false.</returns> /// <exception cref="ArgumentNullException">Thrown when the model is null.</exception> public static bool ValidateModelForCustomRules( object model, ModelStateDictionary modelState, ILogger? logger, string? prefix = null) { bool validationSuccessful = false; try { if (model == null) { throw new ArgumentNullException(nameof(model)); } else { var validationContext = new ValidationContext(model); var validationResults = new List<ValidationResult>(); Validator.TryValidateObject(model, validationContext, validationResults, true); foreach (var result in validationResults) { foreach (var memberName in result.MemberNames) { string key = string.IsNullOrEmpty(prefix) ? memberName : $"{prefix}.{memberName}"; modelState.AddModelError(key, result.ErrorMessage ?? "Error"); } } //Go recursively into depth for all properties of the model object that are objects themselves //we must go manually recursively into depth because API Validator.TryValidateObject does validation //only for class properties on first level foreach (var property in model.GetType().GetProperties()) { if (property.PropertyType.IsClass && property.PropertyType != typeof(string)) { var propertyValue = property.GetValue(model); if (propertyValue != null) { validationSuccessful &= ValidateModelForCustomRules(propertyValue, modelState, logger, property.Name); } } } } } catch (Exception ex) { string methodName = $"Type: {System.Reflection.MethodBase.GetCurrentMethod()?.DeclaringType?.FullName}, " + $"Method: ValidateModel; "; logger?.LogError(ex, methodName); validationSuccessful = false; } return validationSuccessful; } } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //this is typical controller for ASP.NET MVC public class CustomersController : Controller { // some Controller code here //............. //this is typical action for editing customer public async Task<ActionResult> CustomerEdit(CustomerEdit_ViewModel model) { if (model.IsSubmit) { // Model validation is done during model binding but we need more //validating for custom validation rules ValidationUtil.ValidateModelForCustomRules(model, ModelState, null); // we have to check if model is valid if (ModelState.IsValid) { if (model.Customer1 != null) { //we update existing customer in database //redirect to the list of customers } } else { // we go for presentation of validation errors ModelState.AddModelError("", "PleaseCorrectAllErrors"); } } else { ModelState.Clear(); //go for presentation of original data if (model.Id != null) { //get Customer by Id from database } } return View("CustomerEdit", model); } }

جیسا کہ آپ دیکھ سکتے ہیں، ہم نے Customer-partial-class-2 میں ترمیم کی ہے اور Customer_MetaData کلاس شامل کی ہے۔ یہاں کا مقصد NAME پراپرٹی کے لیے اضافی توثیق شامل کرنا ہے، جس میں کم از کم 3 حروف درکار ہیں۔


ASP.NET MVC میں، ہم خرابی کے پیغامات کو درست کرنے اور بازیافت کرنے کے لیے ModelState کا استعمال کر سکتے ہیں۔ نوٹ کریں کہ ہمیں یوٹیلیٹی طریقہ ValidationUtil.ValidateModelForCustomRules کو بھی دستی طور پر اپنی مرضی کی تصدیق کو متحرک کرنے کے لیے استعمال کرنا پڑا۔


کوڈ اور تبصرے اس تکنیک کو سمجھنے کے لیے تمام ضروری تفصیلات فراہم کریں۔

5 نتیجہ

میری C#/EF/ASP.NET 8 MVC ایپلیکیشن میں، میں EF سے تیار کردہ کلاسز کی فعالیت کو بڑھانے کے لیے جزوی C# کلاسز کے ساتھ مندرجہ بالا تکنیکوں کا استعمال کرتا ہوں۔ یہ چالیں عام منظرناموں کو آسان بناتی ہیں، جس سے کوڈ کو مزید جامع اور برقرار رکھنے میں آسانی ہوتی ہے۔