عدم سازگاری با EF
زمانیکه entity1.entity2 دارید یعنی استفاده از خواص راهبری و عموما به صورت lazy loading است؛ خصوصا مطابق تصویری که ارسال کردید (order.OrderProductVariants).
- دریافت اطلاعات OrderProductVariants به همراه entity دربرگیرنده آن به یکباره انجام نشده، بلکه lazy loading در اینجا صورت گرفته (توسط EF؛ نه کتابخانه گزارش ساز).
راه حل: از متد Include استفاده کنید به همراه AsNoTracking که توضیح دادم.
- اینها هم باید در لایه سرویس شما انجام شوند و نه اینجا. لایه سرویس شما فقط باید یک List را بازگشت دهد.
Owin چیست ؟ قسمت اول
ابتدا باید فضای نام System.Web.Routing را در فایل Global.asax اضافه کنیم .
protected void Application_Start(object sender, EventArgs e) { RouteTable.Routes.MapPageRoute("Product", "Product/{Name}", "~/Product.aspx"); }
RouteTable.Routes.MapPageRoute("PostDetail", "Post/{pi}/{pt}", "~/PostShow.aspx");
<a href='<%# string.Format("/Post/{0}/{1}",Eval("PostID"),Eval("PostTitle").ToString().Replace(" ","-")) %>'>
Post/12/چگونه-طراحان-وب-به-جهنم-می-روند!؟
int pi = int.Parse(Page.RouteData.Values["pi"].ToString()); Posts post = (from p in con.Posts where p.PostID == pi select p).FirstOrDefault();
<asp:EntityDataSource ID="EntityDataSource1" runat="server" AutoGenerateWhereClause="True" ConnectionString="name=WebWorkEntities" DefaultContainerName="WebWorkEntities" EnableFlattening="False" EntitySetName="Posts" EntityTypeFilter="Posts" Where="" Select=""> <WhereParameters> <asp:RouteParameter Name="PostID" RouteKey="pi" DbType="Int32" DefaultValue="0" /> </WhereParameters> </asp:EntityDataSource>
protected void Application_Start(object sender, EventArgs e) { RoutingSite(RouteTable.Routes); } public static void RoutingSite(RouteCollection route) { route.MapPageRoute("PostDetail", "Post/{pi}/{pt}", "~/PostShow.aspx"); route.MapPageRoute("RouteAbout", "About-Me", "~/About.aspx"); }
- حالت ارجاع : شماره سند یا Object Id را شامل شده و در صورتیکه به اطلاعاتی نیاز داشتید، باید اطلاعات آن را در یک درخواست جداگانه واکشی نمایید. چون مونگو شامل جوین نبوده و جوینها باید در سطح اپلیکیشن مدیریت شوند.
{ fname:'ali', lname:'yeganeh', accounts:[454354353,3455435] }
- حالت جاسازی سند (یا اسناد تو در تو) Embed : در این حالت سند مورد نظر اطلاعات سند دیگری را در درون خود نگه میدارد. در این حالت به هیچ جوینی نیازی نیست و اطلاعات وابسته، به همراه خود سند اصلی واکشی میشوند. این نکته باید مورد توجه قرار بگیرد که مونگو یک دیتابیس غیر اتمیک هست و در صورتیکه اصل دیتا تغییر کند، تغییر یا به روزرسانی در سندهای Embed انجام نخواهد شد و در صورت نیاز باید خودتان به طور دستی آن را کنترل نمایید.
{ fname:'ali', lname:'yeganeh', accounts:[ { username:"ali", password:"123" }, { username:"reza", password:"456" } ] }
book { name:'Scarlet Letter", Language:"English", Pages:124, ... } publisher { name : "Orielly", ... }
book { name:'Scarlet Letter", Language:"English", Pages:124, ..., publisher: { name : "Orielly", ... } }
- در این حالت در صورتیکه واکشی هر کتاب به همراه اطلاعات ناشر را نیاز داشته باشیم و یا پرس وجوهای ترکیبی نیاز باشد، در سریعترین زمان ممکن واکشی انجام خواهد شد.
- درج و مدیریت آن راحتتر خواهد بود.
- در صورتیکه اطلاعات ناشر نیاز به تغییرات اساسی داشته باشد و باید در تمامی سندها اصلاح گردد، باید تمامی اسناد مربوط به اطلاعات کتاب به روزرسانی شوند که هزینه سنگینتری را خواهد داشت.
- دیتای تکراری زیادی ذخیره خواهد شد و در نتیجه حافظه بیشتری را میطلبد.
- در صورتیکه تنها به اطلاعات ناشر نیاز باشد و اطلاعات ناشر در سند دیگری وجود نداشته باشد و فقط در سند کتاب وجود داشته باشد، واکشی آن هزینه سنگینتری را خواهد طلبید. به همین جهت توصیه میشود در صورتیکه دیتای شما میتواند به صورت یک موجودیت مستقل هم عمل کند، اطلاعات آن در سند دیگری که من به آن سند اصلی میگویم ذخیره شوند تا نمونهها از روی آخرین ویرایش آن ساخته شوند و موقعیکه تنها به واکشی آن اطلاعات نیاز است، همانها بیرون کشیده شوند.
book { name:'Scarlet Letter", Language:"English", Pages:124, ..., publisher:1212121 }
- عدم وجود تکرار اطلاعات
- چون تنها یک سند برای ویرایش وجود دارد، نیازی به اصلاح اسناد توکار نیست و ویرایش، هزینه کمتری خواهد داشت.
- عدم وجود جوین: در صورتیکه نیاز به جوین بزرگی باشد، این نوع جوین باید در سطح برنامه شما انجام شود و هزینه بر خواهد بود.
Post { title:"C#", body:"About C#", tags:['C#','.Net','microsoft'], Categories:[{name:'Programming'}], votes:[{rate:3,user:42342},{rate:5,user:423445},...], comments:[ { text:"my comment1", time:"10/2/1396",...}, ... ] }
{ POST:45453, count:35, comments:[...] }
{ post:345345, capacity:100, count:35, bucket:2, comments:[...] }
- همیشه به این نکته توجه داشته باشید که نباید بگذارید تعداد آرایههای یک سند خیلی بزرگ شوند. در غیر اینصورت کارآیی مونگو به خصوص در حین ویرایش سند پایین خواهد آمد. در حین ویرایش، اگر سندی از اندازهی خود بزرگتر نشود، مشکلی پیش نمیاید ولی اگر فضایی بیش از آنچه که قبلا داشته به آن اضافه شود، سند نیاز به جابجایی و گسترش فضا خواهد داشت. در این حالت باید مونگو سند را به جای دیگری که فضای کافی برای آن وجود دارد، انتقال بدهد و میزان Disk Fragment به طبع بالا خواهد رفت. همچنین اندیسهای آرایهای هم با جابجا شدن دیتا نیاز به، به روزرسانی خواهند داشت و زمانی هم صرف به روزرسانی اندیسها خواهد شد.
- مدیر محصول مونگو اظهار نظر صریحی در این مورد نکردهاست، ولی به نظر میرسد نوع فرمت BSON از یک اسکن خطی در حافظه استفاده میکند و زمان بیشتری صرف پیدا کردن المانهای انتهایی در آرایه خواهد شد؛ پس بیشتر عملیات در این نوع سند، با کندی مواجه خواهند شد. با توجه به کامنتهایی که در سایتها و شبکههای اجتماعی یافت شدهاست، آرایه ای با بیش از صدهزار آیتم ساده میتواند آسیب زا باشد؛ به همین دلیل توصیه میشود که اگر بیش از صدهزار آیتم نیاز است، از همان حالت Bucket استفاده شود.
- استفاده از اندیسها هم سابقهی دیرینهای داشته و سعی کنید کوئری هایی بزنید که بر اساس اندیسهای تعریف شده باشند تا واکشی دیتا سریعتر شود. پس نحوه کوئری نویسی و انتخاب فیلدی که اندیس میشود بسیار مهم است.
- استفاده از Projection تاثیری بر خواندن اسناد ندارد و هر سند به طور کامل واکشی میشود. projection تنها در بارهی ترافیک یا انتقال حجم کمتری از اطلاعات به سمت کلاینت تاثیرگذار میباشد. پس استفاده از projection بجای جدا سازی اسناد را دنبال نکنید.
SharePoint هم وضع بهتری نداره. نصب یک سرویس پک روی آن و جان سالم به در بردن، نیاز به دعا و نذر و نیاز دارد!
علت این مساله هم میتونه موردی باشه که عضو سابق تیم ASP.NET MVC عنوان کرده:
ASP.NET MVC #24
پیروز و موفق باشید
- در مورد تصویر، میتونید از روشهای متداول iTextSharp استفاده کنید. PDF در اصل یک قالب برداری است. شما یک Canvas دارید که میتونید در هر جایی از آن هر شیءایی را قرار دهید. برای نمونه در مثال فوق:
PdfContentByte content = stamper.GetOverContent(pdfReader.NumberOfPages); Image image = Image.GetInstance(imagePath); image.SetAbsolutePosition(450,650); image.ScaleAbsolute(200,200); content.AddImage(image);
با liveshare میتوانید بدون کلون کردن ریپوزیتوری، به صورت هماهنگ با اعضای تیم و به صورت realtime کد خود را ویرایش یا دیباگ کنید:
If you haven’t heard of Live Share, it’s a tool that enables real-time collaborative development with your teammates from the comfort of your own tools. You’re able to share your code, and collaboratively edit and debug, without needing to clone repos or set up environments. It’s easy to get started with Live Share.
چطور باید برای یک پروژه دفترچه مشخصات فنی تهیه کرد؟
مستندات فنی که اصطلاحاً به صورت high-level هستند و خیلی به صورت مداوم بهروز نمیشن رو شاید بهتر باشه خارج از سورسکد ذخیره کرد. روالی که من توی تیمها میبینم اینطور بوده که یک ساختار این مدلی داشتن:
- Archives
- Technical
- ADRs
- Architetures
- QA
- UX Researches
- Meetings
- Releases
برای مستندات فنیتر هم همونطور که اشاره کردید توی پوشه docs/ به صورت markdown قرار میگیرن؛ نکته مهمی که دسترسی رو برای همه سادهتر میکنه داشتن یک فایل ایندکس (markdown) هست.
در نهایت میتونید همه رو داخل همون پوشه docs/ قرار بدید و به صورت قابل دیپلوی در دسترس بقیه اعضای تیم قرار بدید (میتونه بخشی از فرآیند CI/CD باشه مثلاً به محض مرج شدن یک فیچر در برنچ اصلی محتویات پوشه docs/ هم دیپلوی بشه) ابزارهای زیادی هم برای اینکار استفاده میشن مثلاً میتونید از Docusaurus برای اینکار استفاده کنید: