$("#btn1").unbind("click");
EF Code First #10
public class Personel { [Key] public int PersonelID { get; set; } [MaxLength(15)] public string Name { get; set; } [MaxLength(25)] public string Family { get; set; } [MaxLength(10)] public string CodeMelli { get; set; } }
public class PersonalContext : DbContext { public DbSet<Personel> Personel { get; set; } public override int SaveChanges() { return base.SaveChanges(); } }
Install-Package EntityFramework.BulkInsert-ef6
public ActionResult Insert() { int Counter = 1000; List<Personel> Lst = new List<Personel>(); // شبیه سازی خواندن رکوردها از فایل اکسل for (int i = 0; i < Counter; i++) { Lst.Add(new Personel { CodeMelli = "0000000000", Family = "Karimi", Name = "Mohammad" }); } PersonalContext db = new PersonalContext(); db.BulkInsert(Lst); db.SaveChanges(); return View(); }
try { //انتخاب فایل اکسل OpenFileDialog ofd = new OpenFileDialog(); ofd.Title = "انتخاب فایل اکسل حاوی اطلاعات"; ofd.Filter = "فایل اکسل 2003 (*.xls)|*.xls|فایل اکسل 2007 به بعد(*.xlsx)|*.xlsx"; if (ofd.ShowDialog() == DialogResult.OK) { string excelConnectionString = ""; string SourceFilePath = ofd.FileName; //ایجاد کانکشن استرینگ برا خواندن کل اطلاعات از فایل اکسل و ریختن آنها در یک دیتاتیبل به نام dt if (System.IO.Path.GetExtension(ofd.FileName) == ".xlsx") //تشخیص نوع فایل اکسل برای ایجاد کانکشن استرینگ برای نسخههای مختلف اکسل excelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + SourceFilePath + ";Extended Properties=Excel 12.0"; else if (System.IO.Path.GetExtension(ofd.FileName) == ".xls") excelConnectionString = "Provider=Microsoft.Jet.Oledb.4.0;Data Source=" + SourceFilePath + ";Extended Properties=Excel 8.0"; DataTable dt = new DataTable("tblinfos"); using (System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection(excelConnectionString)) { connection.Open(); System.Data.OleDb.OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter("SELECT * FROM [List$]", connection);//List نام شیت در فایل اکسل است da.Fill(dt); connection.Close(); } using (System.Data.OleDb.OleDbConnection connection = new System.Data.OleDb.OleDbConnection(excelConnectionString)) { this.Cursor = Cursors.WaitCursor; connection.Open(); //ایجاد ارتباط با بانک اس کیو ال string sqlConnectionString = @"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\BankDPR.mdf;Max Pool Size=6000; Connection Timeout=50;Integrated Security=True;User Instance=True"; Dataaccess db = new Dataaccess(); DataTable dtr = db.select("Select Top(1) * From tblinfos");//بدست آورن نام ستونهای جدول مورد نظر برای تطبیق با ستونهای فایل اکسل //******************* Fast Copy using (System.Data.SqlClient.SqlBulkCopy bulkCopy = new System.Data.SqlClient.SqlBulkCopy(sqlConnectionString, System.Data.SqlClient.SqlBulkCopyOptions.KeepIdentity))//تعریف یک شی از کلاس SqlBulkCopy { for (int i = 1; i < dtr.Columns.Count; i++) { bulkCopy.ColumnMappings.Add(dt.Columns[i - 1].Caption, dtr.Columns[i].Caption);//با استفاده از خاصیت ColumnMappings نام ستونهای فایل اکسل با نام ستونهای جدول مورد نظر بانک sql تطبیق داده میشود } bulkCopy.DestinationTableName = "tblinfos";//مشخص نمودن نام جدول که قرار است اطلاعات درون ان کپی گردد bulkCopy.WriteToServer(dt);//انجام عملیات کپی اطلاعات از دیتاتیبل با نام dt به بانک } this.Cursor = Cursors.Arrow; MessageBox.Show("اطلاعات از فایل شما خوانده شد"); } } } catch (Exception ex) { this.Cursor = Cursors.Arrow; MessageBox.Show(ex.Message, "error"); }
گاهی از اوقات قبل از درگیر شدن با کاربران (!)، بهتر است حداکثر اندازه مجاز فایل قابل ارسال به سرور را به آنها نمایش داد. درغیراینصورت باید پاسخگوی این باشید که چرا فایل 100 مگابایتی که من ارسال کردم، ذخیره نشده و برنامه کار نمیکنه!
خطای دریافتی این خواهد بود: Maximum request length exceeded
در ASP.Net اگر هیچ تنظیم خاصی صورت نگرفته باشد، حداکثر اندازه فایل قابل ارسال به سرور، 4 مگابایت است. این مورد را در machine.config و یا در web.config میتوان تغییر داد.
برای مثال، جهت بالا بردن اندازه فایل قابل ارسال به سرور در وب کانفیگ برنامه به 39 مگابایت، میتوان سطر زیر را به قسمت system.web اضافه کرد.
<httpRuntime executionTimeout="1200" maxRequestLength="39936" />
اما یک نکته را هم باید درنظر داشت. اگر هاست مورد استفاده شما فایل machine.config را قفل کرده باشد (که از لحاظ امنیتی توصیه میشود)، سطر فوق در web.config هیچ تاثیری نخواهد داشت.
به همین منظور کلاس زیر را تهیه کردهام که تمامی این موارد را لحاظ میکند.
ابتدا مقدار پیش فرض 4 مگابایت درنظر گرفته خواهد شد.
سپس سعی میشود که مقدار مجاز MaxRequestLength از فایل machine.config خوانده شود. همچنین وضعیت قفل بودن آن نیز دریافت میشود.
اگر این قسمت قابل خواندن بود و همچنین قفل نشده بود، مقدار تنظیم شده maxRequestLength در وب کانفیگ، دریافت و استفاده خواهد شد.
و در آخر، اندازه دریافتی، که بر اساس KB است به شکلی قابل خواندن بازگشت داده میشود.
using System;
using System.Configuration;
using System.Web.Configuration;
/// <summary>
/// کلاسی جهت نمایش اندازه مجاز فایل قابل ارسال به سرور
/// </summary>
public class CMaxLimit
{
/// <summary>
/// اندازه مجاز فایل قابل ارسال به سرور
/// </summary>
/// <returns></returns>
public static string MaxFileUploadSizeLimit()
{
//مقدار پیش فرض
int resultKB = 4096;
//machine.config
Configuration mConfig =
WebConfigurationManager.OpenMachineConfiguration();
bool mConfigIsLocked = false;
HttpRuntimeSection section =
mConfig.GetSection("system.web/httpRuntime") as HttpRuntimeSection;
if (section != null)
{
resultKB = section.MaxRequestLength;
mConfigIsLocked = section.ElementInformation.IsLocked;
}
//web.config
if (!mConfigIsLocked)
{
HttpRuntimeSection httpRuntimeSection =
WebConfigurationManager.GetSection("system.web/httpRuntime") as HttpRuntimeSection;
if (httpRuntimeSection != null)
{
resultKB = httpRuntimeSection.MaxRequestLength;
}
}
return
SizeToString(resultKB * 1024);
}
/// <summary>
/// نمایش اندازه یک فایل به صورتی قابل درک
/// </summary>
/// <param name="len">اندازه فایل</param>
/// <returns></returns>
public static string SizeToString(long len)
{
int order = 0;
string[] sizes = new[] { "B", "KB", "MB", "GB" };
while (len >= 1024 && order + 1 < sizes.Length)
{
order++;
len = len / 1024;
}
return String.Format("{0:0.##} {1}", len, sizes[order]);
}
}
معرفی پروژه NotifyPropertyWeaver
- این بسته از طریق آدرس ذیل نیز قابل دریافت است:
https://az320820.vo.msecnd.net/packages/propertychanged.fody.1.42.0.nupkg
همین آدرس را در IE وارد کنید. اگر کار نکرد احتمالا تنظیمات IE شما به هم ریخته است؛ چون تنظیمات آن به صورت مستقیم روی تنظیمات اتصالی برنامههای دات نت تاثیر دارند.
زندگی پس از Google Reader؛ نگاهی به گزینههای مهیا
- پشتیبانی از راست به چپ
- بازکردن سایتهای غیرقابل دسترس در ایران(فیلتر)
- فیلتر نباشه و قول بده در آینده فیلتر نشه!
- محدودیت استفاده نداشته باشه ، کاملا رایگان باشه. [معمولا هزینه پایینی بایت عضویت میگیرند یک هزارم حداقل حقوق (دو دلار از دو هزار دلار) که به پول ما میشه یکصدم حداقل حقوق (دو دلار از 200 دلار ) تازه ما اگر هم بخواهیم پرداخت کنیم کلی در دسر داره ]
اشتباهات متداول برنامهنویسهای دات نت
یک مقایسه. تصویر بدون به هم ریختگی هم در ie و هم فایرفاکس
http://tinyurl.com/ahkw5u
http://tinyurl.com/asohbo
و تصویری که در ie کاملن سالم است و در فایرفاکس فقط یک کلمه آن جلو و عقب شده است
http://tinyurl.com/cf2yos
در هر حال در خوراک خوان عنوان با آبی مشخص شده است و در موارد به هم ریختگی در هر صورت مشخص است. در ضمن در مواردی که انگلیسی و فارسی در عنوان - با هم استفاده شده است در بعضی موارد مشکل بروز میکند که گمان نمیکنم خود فید اصلی هم همیشه و با یک رویه نشان داده شود. موارد بسیاری را شاهدیم که نام وبلاگ یا نویسنده گاهی در راست و گاهی در چپ است و ...
به نظر من نمیرسد مشکل حادی در این رابطه وجود داشته باشد و شاید هم بنده کاملن مقصود شما را متوجه نشده ام که ممنون میشوم توضیح بدهید. در عین حال یک پست در رابطه با فید پرشین بلاگرز را در حال آماده کردن هستم که بزودی پست میکنم. در این پست مقایسه بیشتری به عمل خواهد آمد.
کسی میدونه چرا تمام tag های سایت wordpress فیلتر شده؟
یکی از خاصیتهای جالب این سایت جستجوی یک واژهی کلیدی به صورت زیر است:
به جای keyword عبارت مورد نظر خود را قرار دهید.
مثلا:
http://en.wordpress.com/tag/net/
http://en.wordpress.com/tag/windows-forms/
به این صورت میشود کل وبلاگهای سایت را یکجا تحت نظر داشت یا حتی روی این برچسبها فید هم تعریف میشود و در نرم افزارهای فید خوان قابل استفاده خواهد بود.
در کل بجای فیلتر کردن چند عبارت خاص نباید کل برچسبها رو یکجا فیلتر میکردند.
Service Layer
نقش لایهی سرویس این است که به عنوان یک مدخل ورودی به برنامه کاربردی عمل کند. در برخی مواقع این لایه را به عنوان لایهی Facade نیز میشناسند. این لایه، دادهها را در قالب یک نوع داده ای قوی (Strongly Typed) به نام View Model، برای لایهی Presentation فراهم میکند. کلاس View Model یک Strongly Typed محسوب میشود که نماهای خاصی از دادهها را که متفاوت از دید یا نمای تجاری آن است، بصورت بهینه ارائه مینماید. در مورد الگوی View Model در مباحث بعدی بیشتر صحبت خواهم کرد.
الگوی Facade یک Interface ساده را به منظور کنترل دسترسی به مجموعه ای از Interfaceها و زیر سیستمهای پیچیده ارائه میکند. در مباحث بعدی در مورد آن بیشتر صحبت خواهم کرد.
کلاسی با نام ProductViewModel را با کد زیر به پروژه SoCPatterns.Layered.Service اضافه کنید:
public class ProductViewModel { Public int ProductId {get; set;} public string Name { get; set; } public string Rrp { get; set; } public string SellingPrice { get; set; } public string Discount { get; set; } public string Savings { get; set; } }
برای اینکه کلاینت با لایهی سرویس در تعامل باشد باید از الگوی Request/Response Message استفاده کنیم. بخش Request توسط کلاینت تغذیه میشود و پارامترهای مورد نیاز را فراهم میکند. کلاسی با نام ProductListRequest را با کد زیر به پروژه SoCPatterns.Layered.Service اضافه کنید:
using SoCPatterns.Layered.Model; namespace SoCPatterns.Layered.Service { public class ProductListRequest { public CustomerType CustomerType { get; set; } } }
در شی Response نیز بررسی میکنیم که درخواست به درستی انجام شده باشد، دادههای مورد نیاز را برای کلاینت فراهم میکنیم و همچنین در صورت عدم اجرای صحیح درخواست، پیام مناسب را به کلاینت ارسال مینماییم. کلاسی با نام ProductListResponse را با کد زیر به پروژه SoCPatterns.Layered.Service اضافه کنید:
public class ProductListResponse { public bool Success { get; set; } public string Message { get; set; } public IList<ProductViewModel> Products { get; set; } }
به منظور تبدیل موجودیت Product به ProductViewModel، به دو متد نیاز داریم، یکی برای تبدیل یک Product و دیگری برای تبدیل لیستی از Product. شما میتوانید این دو متد را به کلاس Product موجود در Domain Model اضافه نمایید، اما این متدها نیاز واقعی منطق تجاری نمیباشند. بنابراین بهترین انتخاب، استفاده از Extension Methodها میباشد که باید برای کلاس Product و در لایهی سرویس ایجاد نمایید. کلاسی با نام ProductMapperExtensionMethods را با کد زیر به پروژه SoCPatterns.Layered.Service اضافه کنید:
public static class ProductMapperExtensionMethods { public static ProductViewModel ConvertToProductViewModel(this Model.Product product) { ProductViewModel productViewModel = new ProductViewModel(); productViewModel.ProductId = product.Id; productViewModel.Name = product.Name; productViewModel.RRP = String.Format(“{0:C}”, product.Price.RRP); productViewModel.SellingPrice = String.Format(“{0:C}”, product.Price.SellingPrice); if (product.Price.Discount > 0) productViewModel.Discount = String.Format(“{0:C}”, product.Price.Discount); if (product.Price.Savings < 1 && product.Price.Savings > 0) productViewModel.Savings = product.Price.Savings.ToString(“#%”); return productViewModel; } public static IList<ProductViewModel> ConvertToProductListViewModel( this IList<Model.Product> products) { IList<ProductViewModel> productViewModels = new List<ProductViewModel>(); foreach(Model.Product p in products) { productViewModels.Add(p.ConvertToProductViewModel()); } return productViewModels; } }
حال کلاس ProductService را جهت تعامل با کلاس سرویس موجود در Domain Model و به منظور برگرداندن لیستی از محصولات و تبدیل آن به لیستی از ProductViewModel، ایجاد مینماییم. کلاسی با نام ProductService را با کد زیر به پروژه SoCPatterns.Layered.Service اضافه کنید:
public class ProductService { private Model.ProductService _productService; public ProductService(Model.ProductService ProductService) { _productService = ProductService; } public ProductListResponse GetAllProductsFor( ProductListRequest productListRequest) { ProductListResponse productListResponse = new ProductListResponse(); try { IList<Model.Product> productEntities = _productService.GetAllProductsFor(productListRequest.CustomerType); productListResponse.Products = productEntities.ConvertToProductListViewModel(); productListResponse.Success = true; } catch (Exception ex) { // Log the exception… productListResponse.Success = false; // Return a friendly error message productListResponse.Message = ex.Message; } return productListResponse; } }
کلاس Service تمامی خطاها را دریافت نموده و پس از مدیریت خطا، پیغامی مناسب را به کلاینت ارسال میکند. همچنین این لایه محل مناسبی برای Log کردن خطاها میباشد. در اینجا کد نویسی لایه سرویس به پایان رسید و در ادامه به کدنویسی Data Layer میپردازیم.
Data Layer
برای ذخیره سازی محصولات، یک بانک اطلاعاتی با نام Shop01 ایجاد کنید که شامل جدولی به نام Product با ساختار زیر باشد:
برای اینکه کدهای بانک اطلاعاتی را سریعتر تولید کنیم از روش Linq to SQL در Data Layer استفاده میکنم. برای این منظور یک Data Context برای Linq to SQL به این لایه اضافه میکنیم. بر روی پروژه SoCPatterns.Layered.Repository کلیک راست نمایید و گزینه Add > New Item را انتخاب کنید. در پنجره ظاهر شده و از سمت چپ گزینه Data و سپس از سمت راست گزینه Linq to SQL Classes را انتخاب نموده و نام آن را Shop.dbml تعیین نمایید.
از طریق پنجره Server Explorer به پایگاه داده مورد نظر متصل شوید و با عمل Drag & Drop جدول Product را به بخش Design کشیده و رها نمایید.
اگر به یاد داشته باشید، در لایه Model برای برقراری ارتباط با پایگاه داده از یک Interface به نام IProductRepository استفاده نمودیم. حال باید این Interface را پیاده سازی نماییم. کلاسی با نام ProductRepository را با کد زیر به پروژه SoCPatterns.Layered.Repository اضافه کنید:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using SoCPatterns.Layered.Model; namespace SoCPatterns.Layered.Repository { public class ProductRepository : IProductRepository { public IList<Model.Product> FindAll() { var products = from p in new ShopDataContext().Products select new Model.Product { Id = p.ProductId, Name = p.ProductName, Price = new Model.Price(p.Rrp, p.SellingPrice) }; return products.ToList(); } } }
در متد FindAll، با استفاده از دستورات Linq to SQL، لیست تمامی محصولات را برگرداندیم. کدنویسی لایهی Data هم به پایان رسید و در ادامه به کدنویسی لایهی Presentation و UI میپردازیم.
Presentation Layer
به منظور جداسازی منطق نمایش (Presentation) از رابط کاربری (User Interface)، از الگوی Model View Presenter یا همان MVP استفاده میکنیم که در مباحث بعدی با جزئیات بیشتری در مورد آن صحبت خواهم کرد. یک Interface با نام IProductListView را با کد زیر به پروژه SoCPatterns.Layered.Presentation اضافه کنید:
using SoCPatterns.Layered.Service; public interface IProductListView { void Display(IList<ProductViewModel> Products); Model.CustomerType CustomerType { get; } string ErrorMessage { set; } }
این Interface توسط Web Formهای ASP.NET و یا Win Formها باید پیاده سازی شوند. کار با Interfaceها موجب میشود تا تست Viewها به راحتی انجام شوند. کلاسی با نام ProductListPresenter را با کد زیر به پروژه SoCPatterns.Layered.Presentation اضافه کنید:
using SoCPatterns.Layered.Service; namespace SoCPatterns.Layered.Presentation { public class ProductListPresenter { private IProductListView _productListView; private Service.ProductService _productService; public ProductListPresenter(IProductListView ProductListView, Service.ProductService ProductService) { _productService = ProductService; _productListView = ProductListView; } public void Display() { ProductListRequest productListRequest = new ProductListRequest(); productListRequest.CustomerType = _productListView.CustomerType; ProductListResponse productResponse = _productService.GetAllProductsFor(productListRequest); if (productResponse.Success) { _productListView.Display(productResponse.Products); } else { _productListView.ErrorMessage = productResponse.Message; } } } }
کلاس Presenter وظیفهی واکشی داده ها، مدیریت رویدادها و بروزرسانی UI را دارد. در اینجا کدنویسی لایهی Presentation به پایان رسیده است. از مزایای وجود لایهی Presentation این است که تست نویسی مربوط به نمایش دادهها و تعامل بین کاربر و سیستم به سهولت انجام میشود بدون آنکه نگران دشواری Unit Test نویسی Web Formها باشید. حال میتوانید کد نویسی مربوط به UI را انجام دهید که در ادامه به کد نویسی در Win Forms و Web Forms خواهیم پرداخت.