+
کوئری شما فقط یک expression است. هنوز اجرا نشده. اجرای یک عبارت با فراخوانی متدهایی مانند ToList، FirstOrDefault و امثال آن رخ میدهد. به این مورد deferred execution گفته میشود (قسمت دهم سری ef code first سایت جاری).
// Cv2.ImRead using (var src = new Mat(@"..\..\Images\Penguin.Png", LoadMode.AnyDepth | LoadMode.AnyColor)) using (var dst = new Mat()) { Cv2.CvtColor(src, dst, ColorConversion.BgrToGray); // How to export using (var bitmap = dst.ToBitmap()) // => OpenCvSharp.Extensions.BitmapConverter.ToBitmap(dst) { bitmap.Save("gray.png", ImageFormat.Png); } using (new Window("BgrToGray C++: src", image: src)) using (new Window("BgrToGray C++: dst", image: dst)) { Cv2.WaitKey(); } }
cv::Mat src = cv::imread ("foo.jpg"); cv::Mat dst; cv::cvtColor (src, dst, CV_BGR2GRAY);
using (var src = new IplImage(@"..\..\Images\Penguin.Png", LoadMode.AnyDepth | LoadMode.AnyColor)) using (var dst = new IplImage(src.Size, src.Depth, src.NChannels)) { for (var y = 0; y < src.Height; y++) { for (var x = 0; x < src.Width; x++) { CvColor pixel = src[y, x]; dst[y, x] = new CvColor { B = (byte)(255 - pixel.B), G = (byte)(255 - pixel.G), R = (byte)(255 - pixel.R) }; } } // [C] Accessing Pixel // https://github.com/shimat/opencvsharp/wiki/%5BC%5D-Accessing-Pixel using (new CvWindow("C Interface: Src", image: src)) using (new CvWindow("C Interface: Dst", image: dst)) { Cv.WaitKey(0); } }
// Cv2.ImRead using (var src = new Mat(@"..\..\Images\Penguin.Png", LoadMode.AnyDepth | LoadMode.AnyColor)) using (var dst = new Mat()) { src.CopyTo(dst); for (var y = 0; y < src.Height; y++) { for (var x = 0; x < src.Width; x++) { var pixel = src.Get<Vec3b>(y, x); var newPixel = new Vec3b { Item0 = (byte)(255 - pixel.Item0), // B Item1 = (byte)(255 - pixel.Item1), // G Item2 = (byte)(255 - pixel.Item2) // R }; dst.Set(y, x, newPixel); } } // [Cpp] Accessing Pixel // https://github.com/shimat/opencvsharp/wiki/%5BCpp%5D-Accessing-Pixel //Cv2.NamedWindow(); //Cv2.ImShow(); using (new Window("C++ Interface: Src", image: src)) using (new Window("C++ Interface: Dst", image: dst)) { Cv2.WaitKey(0); } }
string data = null; var result = data ?? "value";
if (data == null) { data = "value"; } var result = data;
class Response { public string Result { set; get; } public int Code { set; get; } } class WebRequest { public Response GetDataFromWeb(string url) { // ... return new Response { Result = null }; } }
var webData = new WebRequest().GetDataFromWeb("https://www.dntips.ir/"); if (webData != null && webData.Result != null) { Console.WriteLine(webData.Result); }
if (webData?.Result != null) { Console.WriteLine(webData.Result); }
if (x != null) { x.Dispose(); }
x?.Dispose();
var copy = OnMyEvent; if (copy != null) { copy(this, new EventArgs()); }
OnMyEvent?.Invoke(this, new EventArgs());
var code = webData?.Code;
if (webData?.Code > 0) { }
int count = response?.Results?.Count ?? 0;
int? x = 10; //var value = x?.Value; // invalid Console.WriteLine(x?.ToString());
if (response != null && response.Results != null && response.Results.Addresses != null && response.Results.Addresses[0] != null && response.Results.Addresses[0].Zip == "63368") { }
if(response?.Results?.Addresses?[0]?.Zip == "63368") { }
public void DoSomething(Customer customer) { string address = customer?.Employees ?.SingleOrDefault(x => x.IsAdmin)?.Address?.ToString(); SendPackage(address); }
public void DoSomething(Customer customer) { Contract.Requires(customer != null); string address = customer.GetAdminAddress(); SendPackage(address); }
InvalidCastExceptio
internal class Employee { ... } public sealed class Program { public static void Main() { // بدون ذکر نام والد تبدیل صورت میگیرد Object o = new Employee(); // برای تبدیل والد به یکی از مشتقات آن نیاز است // نوع آن به طور صریح ذکر گردد // در بعضی زبانهای مثل ویژوال بیسیک نیازی به ذکر آن نیست Employee e = (Employee) o; } }
Object o = new Object(); Boolean b1 = (o is Object); // b1 is true. Boolean b2 = (o is Employee); // b2 is false.
پی نوشت :در این بررسی اگر شیء نال باشد، مقدار برگشتی همیشه false است. چون به هیچ نوعی قابل تبدیل نیست.نحوهی استفادهی از کلمه کلیدی is در این تبدیل به شکل زیر است:
if (o is Employee) { Employee e = (Employee) o; }
Employee e = o as Employee; if (e != null) { ..... }
System.Text
public sealed class Program { public static void Main() { System.IO.FileStream fs = new System.IO.FileStream(...); System.Text.StringBuilder sb = new System.Text.StringBuilder(); } }
using System.IO; // Try prepending "System.IO." using System.Text; // Try prepending "System.Text." public sealed class Program { public static void Main() { FileStream fs = new FileStream(...); StringBuilder sb = new StringBuilder(); } }
using Microsoft; using Dotnettips ; public sealed class Program { public static void Main() { Widget w = new Widget();// An ambiguous reference } }
'Widget' is an ambiguous reference between 'Microsoft.Widget' and 'Dotnettips.Widget
using Microsoft; using Dotnettips; public sealed class Program { public static void Main() { Dotnettips.Widget w = new Dotnettips.Widget(); // Not ambiguous } }
using Microsoft; using Dotnettips; using DotnettipsWidget = Dotnettips.Widget; public sealed class Program { public static void Main() { DotnettipsWidget w = new DotnettipsWidget (); // No error now } }
- اینکه شما بروز یک مشکل رو با یک عدد منفی از یک متد بازگشت میدید یعنی هنوز دید زبان C رو دارید. در دات نت وجود استثناءها دقیقا برای ننوشتن return 0 یا -1 و شبیه به آن هست. در این حالت برنامه خودکار در هر سطحی که باشد، ادامهاش متوقف میشه و نیازی نیست تا مدام خروجی یک متد رو چک کرد.
- اینکه در یک متد کانکشنی برقرار شده و بسته شده یعنی ضعف کپسوله سازی مفاهیم ADO.NET. نباید این مسایل رو مدام در تمام متدها تکرار کرد. میشه یک متد عمومی ExecSQL درست کرد بجای تکرار مدام یک سری کد.
- یک سری از اشیاء اینترفیس IDisposable رو پیاده سازی میکنند مثل همین شیء اتصالی که ذکر شد. در این حالت میشه از using استفاده کرد بجای try/finally و اون وقت به دوتا using نیاز خواهید داشت یعنی شیء Command هم نیاز به try/finally داره.
در این مقاله میخواهیم نحوهٔ ساخت اشیایی با خصوصیات Enumerable را بررسی کنیم. بررسی ویژگی این اشیاء دارای اهمیت است حداقل به این دلیل که پایهٔ یکی از قابلیت مهم زبانی سیشارپ یعنی LINQ هستند. برای یافتن پیشزمینهای در این موضوع خواندن این مقالههای بسیار خوب (۱ و ۲) نیز توصیه میشود.
اشیاء Enumerable یا بهعبارت دیگر اشیائی که اینترفیس IEnumerable را پیادهسازی میکنند، دامنهٔ گستردهای از Collectionهای CLI را شامل میشوند. همانطور که در نمودار زیر نیز میتوانید مشاهده کنید IEnumerable (از نوع غیر Generic آن) در بالای سلسله مراتب اینترفیسهای Collectionهای CLI قرار دارد:
درخت اینترفیسهای Collectionها در CLI منبع
IEnumerableها همچنین دارای اهمیت دیگری نیز هستند؛ قابلیتهای LINQ که از داتنت ۳.۵ به داتنت اضافه شدند بهعنوان Extensionهای این اینترفیس تعریف شدهاند و پیادهسازی Linq to Objects را میتوانید در کلاس استاتیک System.Linq.Enumerable در System.Core مشاهده کنید. (میتوانید برای دیدن آن را با ILDasm یا Reflector باز کنید یا پیادهسازی آزاد آن در پروژهٔ Mono را اینجا مشاهده کنید که برای شناخت بیشتر LINQ واقعاً مفید است.)
همچنین این Enumerableها هستند که foreach را امکانپذیر میکنند. به عبارتی دیگر هر شئای که قرار باشد در foreach (var x in object) قرار بگیرد و بدین طریق اشیاء درونیاش را برای پیمایش یا عملی خاص قرار دهد باید Enumerable باشد.
همانطور که قبلاً هم اشاره شد IEnumerable از نوع غیر Generic در بالای نمودار Collectionها قرار دارد و حتی IEnumerable از نوع Generic نیز باید آن را پشتیبانی کند. این موضوع به احتمال به این دلیل در طراحی لحاظ شد که مهاجرت به .NET 2.0 که قابلیتهای Generic را افزوده بود سادهتر کند. IEnumerable همچنین قابلیت covariance که از قابلیتهای جدید C# 4.0 هست را دارا است (در اصل IEnumerable دارای Generic از نوع out است).
Enumerableها همانطور که از اسم اینترفیس IEnumerable انتظار میرود اشیایی هستند که میتوانند یک شئ Enumerator که IEnumerator را پیادهسازی کردهاست را از خود ارائه دهند. پس طبیعی است برای فهم و درک دلیل وجودی Enumerable باید Enumerator را بررسی کنیم.
Enumerator شئ است که در یک پیمایش یا بهعبارت دیگر گذر از روی تکتک عضوها ایجاد میشود که با حفظ موقعیت فعلی و پیمایش امکان ادامهٔ پیمایش را برای ما فراهم میآورد. اگر بخواهید آن را در حقیقت بازسازی کنید شئ Enumerator بهمانند کاغذ یا جسمی است که بین صفحات یک کتاب قرار میدهید که مکانی که در آن قرار دارید را گم نکنید؛ در این مثال، Enumerable همان کتاب است که قابلیت این را دارد که برای پیمایش به وسیلهٔ قرار دادن یک جسم در وسط آن را دارد.
حال برای اینکه دید بهتری از رابطهٔ بین Enumerable و Enumerator از نظر برنامهنویسی به این موضوع پیدا کنیم یک کد نمونهٔ عملی را بررسی میکنیم.
در اینجا نمونهٔ ساده و خوانایی از استفاده از یک List برای پیشمایش تمامی اعداد قرار دارد:
List<int> list = new List<int>(); list.Add(1); list.Add(2); list.Add(3); foreach (int i in list) { Console.WriteLine(i); }
همانطور که قبلاً اشاره foreach نیاز به یک Enumerable دارد و List هم با پیادهسازی IList که گسترشی از IEnumerable هست نیز یک نوع Enumerable هست. اگر این کد را Compile کنیم و IL آن را بررسی کنیم متوجه میشویم که CLI در اصل چنین کدی را برای اجرا میبینید:
List<int> list = new List<int>(); list.Add(1); list.Add(2); list.Add(3); IEnumerator<int> listIterator = list.GetEnumerator(); while (listIterator.MoveNext()) { Console.WriteLine(listIterator.Current); } listIterator.Dispose();
(میتوان از using استفاده نمود که Dispose را خود انجام دهد که اینجا برای سادگی استفاده نشدهاست.)
همانطور که میبینیم یک Enumerator برای Enumerable ما (یعنی List) ایجاد شد و پس از آن با پرسش این موضوع که آیا این پیمایش امکان ادامه دارد، کل اعضا پیمودهشده و عمل مورد نظر ما بر آنها انجام شدهاست.
خب، تا اینجای کار با خصوصیات و اهمیت Enumeratorها و Enumerableها آشنا شدیم، حال نوبت به آن میرسد که بررسی کنیم آنها را چگونه میسازند و بعد از آن با کاربردهای فراتری از آنها نسبت به پیمایش یک List آشنا شویم.
همانطور که اشاره شد ایجاد اشیاء Enumerable به اشیاء Enumerator مربوط است، پس ما در یک قطعه کد که پیمایش از روی یک آرایه را فراهم میآورد ایجاد هر دوی آنها و رابطهٔ بینشان را بررسی میکنیم.
public class ArrayEnumerable<T> : IEnumerable<T> { private T[] _array; public ArrayEnumerable(T[] array) { _array = array; } public IEnumerator<T> GetEnumerator() { return new ArrayEnumerator<T>(_array); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return GetEnumerator(); } } public class ArrayEnumerator<T> : IEnumerator<T> { private T[] _array; public ArrayEnumerator(T[] array) { _array = array; } public int index = -1; public T Current { get { return _array[index]; } } object System.Collections.IEnumerator.Current { get { return this.Current; } } public bool MoveNext() { index++; return index < _array.Length; } public void Reset() { index = 0; } public void Dispose() { } }
using System; using System.Collections; class ProgrArrayListExample { static void Main() { ArrayList list = new ArrayList(); list.Add("Hello"); list.Add(5); list.Add(3.14159); list.Add(DateTime.Now); for (int i = 0; i < list.Count; i++) { object value = list[i]; Console.WriteLine("Index={0}; Value={1}", i, value); } } }
Index=0; Value=Hello Index=1; Value=5 Index=2; Value=3.14159 Index=3; Value=29.02.2015 23:17:01
ArrayList list = new ArrayList(); list.Add(2); list.Add(3.5f); list.Add(25u); list.Add(" ریال"); dynamic sum = 0; for (int i = 0; i < list.Count; i++) { dynamic value = list[i]; sum = sum + value; } Console.WriteLine("Sum = " + sum); // Output: Sum = 30.5ریال
GenericType<T> instance = new GenericType<T>();
List<int> intList = new List<int>(); List<bool> boolList = new List<bool>(); List<double> realNumbersList = new List<double>();
List<int> intList = new List<int>();
استفاده از لیست پیوندی برای پیاده سازی پشته:
Stack<string> stack = new Stack<string>(); stack.Push("A"); stack.Push("B"); stack.Push("C"); while (stack.Count > 0) { string letter= stack.Pop(); Console.WriteLine(letter); } //خروجی //C //B //A
ابتدای آرایه مکانی است که عنصر از آنجا برداشته میشود و Head به آن اشاره میکند و tail هم به انتهای آرایه که جهت درج عنصر جدید مفید است. با برداشتن هر خانهای که head به آن اشاره میکند، head یک خانه به سمت جلو حرکت میکند و زمانی که Head از tail بیشتر شود، یعنی اینکه دیگر عنصری یا المانی در صف وجود ندارد و head و Tail به ابتدای صف حرکت میکنند. در این حالت موقعی که المان جدیدی قصد اضافه شدن داشته باشد، افزودن، مجددا از اول صف آغاز میشود و به این صفها، صف حلقوی میگویند.
عملیات اصلی صف دو مورد هستند enqueue که المان جدید را در انتهای صف قرار میدهد و dequeue اولین المان صف را بیرون میکشد.
پیاده سازی صف به صورت پویا با لیستهای پیوندی
برای پیاده سازی صف، لیستهای پیوندی یک طرفه کافی هستند:
در این حالت عنصر جدید مثل سابق به انتهای لیست اضافه میشود و برای حذف هم که از اول لیست کمک میگیریم و با حذف عنصر اول، متغیر Head به عنصر یا المان دوم اشاره خواهد کرد.
کلاس از پیش آمده صف در دات نت <Queue<T است و نحوهی استفاده آن بدین شکل است:
static void Main() { Queue<string> queue = new Queue<string>(); queue.Enqueue("Message One"); queue.Enqueue("Message Two"); queue.Enqueue("Message Three"); queue.Enqueue("Message Four"); while (queue.Count > 0) { string msg = queue.Dequeue(); Console.WriteLine(msg); } } //خروجی //Message One //Message Two //Message Thre //Message Four
public interface IBinaryOperations<T> { T Add(T arg1, T arg2); T Subtract(T arg1, T arg2); T Multiply(T arg1, T arg2); T Divide(T arg1, T arg2); }
public class BasicMath : IBinaryOperations<int> { public int Add(int arg1, int arg2) { return arg1 + arg2; } public int Subtract(int arg1, int arg2) { return arg1 - arg2; } public int Multiply(int arg1, int arg2) { return arg1 * arg2; } public int Divide(int arg1, int arg2) { return arg1 / arg2; } }
static void Main(string[] args) { Console.WriteLine("***** Generic Interfaces *****\n"); BasicMath m = new BasicMath(); Console.WriteLine("1 + 1 = {0}", m.Add(1, 1)); Console.ReadLine(); }
public class BasicMath : IBinaryOperations<double> { public double Add(double arg1, double arg2) { return arg1 + arg2; } ... }
public static void Initialize(Assembly assembly) { //register global convertors. AutoMapper.Mapper.CreateMap<DateTime, string>().ConvertUsing<DateTimeToPersianDateTimeConverter>(); var typesToMap = from t in assembly.GetTypes() let attr = t.GetCustomAttribute<MapFromAttribute>() where attr != null select new {SourceType = attr.SourceType, Destination = t, Attribute = attr}; foreach (var map in typesToMap) { AutoMapper.Mapper.CreateMap(map.SourceType, map.Destination) .DoMapForMemberAttribute() // for different property names in source and destination .DoIgnoreMapAttribute()// ignore specified properties .DoUseValueResolverAttribute()// set value resolvers .DoIgnoreAllNonExisting()// its have to be the latest. ; } //endeach AutoMapper.Mapper.AssertConfigurationIsValid(); }
public static IMappingExpression DoMapForMemberAttribute(this IMappingExpression expression) { var ok = from p in expression.TypeMap.DestinationType.GetProperties() let attr = p.GetCustomAttribute<MapForMemberAttribute>() where attr != null select new {AttributeValue = attr, PropertyName = p.Name}; foreach (var property in ok) { expression.ForMember(property.PropertyName, opt => opt.MapFrom(property.AttributeValue.MemberToMap)); } return expression; }
public static IMappingExpression DoIgnoreAttribute(this IMappingExpression expression) { foreach (var property in expression.TypeMap.DestinationType.GetProperties() .Where(x => x.GetCustomAttribute<IgnoreMapAttribute>() != null)) { expression.ForMember(property.Name, opt => opt.Ignore()); } return expression; }
public static IMappingExpression DoUseValueResolverAttribute(this IMappingExpression expression) { var ok = from p in expression.TypeMap.DestinationType.GetProperties() let attr = p.GetCustomAttribute<UseValueResolverAttribute>() where attr != null select new {AttributeValue = attr, PropertyName = p.Name}; foreach (var property in ok) { expression.ForMember(property.PropertyName, opt => opt.ResolveUsing(property.AttributeValue.ValueResolver)); } return expression; }
public static IMappingExpression DoIgnoreAllNonExisting(this IMappingExpression expression) { var attr = expression.TypeMap.DestinationType.GetCustomAttribute<MapFromAttribute>(); if (attr?.IgnoreAllNonExistingProperty == false)//instead of if(attr == null || attr.IgnoreAllNonExistingProperty == false) return expression; foreach (var property in expression.TypeMap.GetUnmappedPropertyNames()) { expression.ForMember(property, opt => opt.Ignore()); } return expression; }
public class Student { public virtual int Id { set; get; } public virtual string Name { set; get; } public virtual string Family { set; get; } public virtual string Email { set; get; } public virtual DateTime RegisterDateTime { set; get; } public virtual ICollection<Book> Books { set; get; } } public class Book { public virtual int Id { set; get; } public virtual string Name { set; get; } public virtual DateTime BorrowDateTime { set; get; } public virtual DateTime ExpiredDateTime { set; get; } public virtual decimal Price { set; get; } [ForeignKey("StudentIdFk")] public virtual Student Student { set; get; } public virtual int StudentIdFk { set; get; } }
[MapFrom(typeof (Student), ignoreAllNonExistingProperty: true, alsoCopyMetadata: true)] public class AdminStudentViewModel { // [IgnoreMap] public int Id { set; get; } [MapForMember("Name")] public string FirstName { set; get; } [MapForMember("Family")] public string LastName { set; get; }
[IgnoreMap] public string Email { set; get; } [MapForMember("RegisterDateTime")] public string RegisterDateTimePersian { set; get; } [UseValueResolver(typeof (BookCountValueResolver))] public int BookCounts { set; get; } [UseValueResolver(typeof (BookPriceValueResolver))] public decimal TotalBookPrice { set; get; } };
public class BookCountValueResolver : ValueResolver<Student, int> { protected override int ResolveCore(Student source) => source.Books.Count; }; public class BookPriceValueResolver : ValueResolver<Student, decimal> { protected override decimal ResolveCore(Student source) => source.Books.Sum(b => b.Price); };
static void Main(string[] args) { var assemblyToLoad = Assembly.GetAssembly(typeof (AdminStudentViewModel));//get assembly global::AttributesForAutomapper.Configuration.Initialize(assemblyToLoad);//init automaper IList<Student> lst; using (var context = new MySampleContext()) { lst = context.Students.Include(x => x.Books).ToList(); } foreach (var student in lst) { WriteLine( $"[{student.Id}]*\n{student.Name} {student.Family}.\nmailto:{student.Email}.\nRegistered at'{student.RegisterDateTime}'"); foreach (var book in student.Books) WriteLine($"\tBook name:{book.Name}, Book price:{book.Price}"); } var lstViewModel = AutoMapper.Mapper.Map<IList<Student>, IList<AdminStudentViewModel>>(lst); foreach (var adminStudentViewModel in lstViewModel) { WriteLine( $"[{adminStudentViewModel.Id}]*\n\t{adminStudentViewModel.FirstName} {adminStudentViewModel.LastName}.\n\t" + $"mailto:{adminStudentViewModel.Email}.\n\tRegistered at'{adminStudentViewModel.RegisterDateTimePersian}'\n\t" + $"Book Counts: {adminStudentViewModel.BookCounts} with total price of {adminStudentViewModel.TotalBookPrice}"); } WriteLine("Press any key to exit..."); ReadKey(); }
[1]* Morteza Raeisi. mailto:MrRaeisi@outlook.com. Registered at'23/08/1392 19:11:43' // I'm using Windows 10 with Persian calendar as default, On other OS or calendar settings, this value is different. Book name:AutoMapper Attr, Book price:1000.00 Book name:Second Book, Book price:2500.00 Book name:Hungry Book, Book price:2500.00 ... [1]* Morteza Raeisi. //MapForMemebers mailto:. // IgnoreMap Registered at'1392/08/23 19:11' // Convert using Book Counts: 3 with total price of 6000.00 // Value resolvers ...
@page "/hotel-room/create"
@page "/hotel-room/create" @page "/hotel-room/edit/{Id:int}"
@code { // ... [Parameter] public int? Id { get; set; } protected override async Task OnInitializedAsync() { if (Id.HasValue) { // Update Mode Title = "Update"; HotelRoomModel = await HotelRoomService.GetHotelRoomAsync(Id.Value); } else { // Create Mode HotelRoomModel = new HotelRoomDTO(); } } // ... }
<EditForm Model="HotelRoomModel" OnValidSubmit="HandleHotelRoomUpsert">
<tr> <td>@room.Name</td> <td>@room.Occupancy</td> <td>@room.RegularRate.ToString("c")</td> <td>@room.SqFt</td> <td> <NavLink href="@($"hotel-room/edit/{room.Id}")" class="btn btn-primary">Edit</NavLink> </td> </tr>
namespace BlazorServer.Services { public interface IHotelRoomService { Task<bool> IsRoomUniqueAsync(string name, int roomId); // ... } } namespace BlazorServer.Services { public class HotelRoomService : IHotelRoomService { // ... public Task<bool> IsRoomUniqueAsync(string name, int roomId) { if (roomId == 0) { // Create Mode return _dbContext.HotelRooms .ProjectTo<HotelRoomDTO>(_mapperConfiguration) .AnyAsync(x => x.Name != name); } else { // Edit Mode return _dbContext.HotelRooms .ProjectTo<HotelRoomDTO>(_mapperConfiguration) .AnyAsync(x => x.Name != name && x.Id != roomId); } } } }
// ... @inject IJSRuntime JsRuntime @code { // ... private async Task HandleHotelRoomUpsert() { var isRoomUnique = await HotelRoomService.IsRoomUniqueAsync(HotelRoomModel.Name, HotelRoomModel.Id); if (!isRoomUnique) { await JsRuntime.ToastrError($"The room name: `{HotelRoomModel.Name}` already exists."); return; } if (HotelRoomModel.Id != 0 && Title == "Update") { // Update Mode var updateResult = await HotelRoomService.UpdateHotelRoomAsync(HotelRoomModel.Id, HotelRoomModel); await JsRuntime.ToastrSuccess($"The `{HotelRoomModel.Name}` updated successfully."); } else { // Create Mode var createResult = await HotelRoomService.CreateHotelRoomAsync(HotelRoomModel); await JsRuntime.ToastrSuccess($"The `{HotelRoomModel.Name}` created successfully."); } NavigationManager.NavigateTo("hotel-room"); } }