نظرات مطالب
EF Code First #12
- ابتدای کار یک روش غلط رو شروع کرده، بعد اواسط کار اون رو نقد کرده و رد.
- چون از لایه سرویس استفاده نکرده کل منطق کار رو برده داخل کنترلرها.
- از تزریق وابستگی‌ها استفاده نکرده، بنابراین برخلاف شکلی که در ابتدای کار گذاشته، کنترلرهاش رو نمی‌تونه مستقل از یک سری کلاس کاملا مشخص، تست کنه.
- الگوی مخزنی که ارائه داده در این مثال ساده کار می‌کنه اما اگر قرار باشه با چند موجودیت کار کرد و نتیجه رو ترکیب، کارآیی خوبی نداره چون خیلی از قابلیت‌های ذاتی EF مثل کوئری‌های به تاخیر افتاده (deferred LINQ queries) در اینجا قابل پیاده سازی نیست. اگر هم بخوان این رو اضافه کنن باید به لایه مخزن خروجی IQueryable اضافه کنن که به یک طراحی نشتی دار خواهند رسید چون انتهای کار با خروجی IQueryable کاملا باز باقی می‌ماند (نمونه‌اش متد Get ایی است که طراحی کرده).
یا یکی دیگر از اهداف ظاهری لایه مخزن، امکان تعویض آن در صورت نیاز است و مثلا کوچ به یک ORM دیگر. دنیای واقعی: include ایی که اینجا تعریف شده فقط در EF وجود خارجی دارد یا یک سری از نکات دیگر بکار گرفته شده در این الگوی مخزن. (در قسمت 11 سری EF سایت بحث شده)
- در مثالی که زده باگ امنیتی وجود دارد. متد Updateاش به دلیل عدم استفاده از ViewModel آسیب پذیر هست. (در این مورد در سری MVC بحث شده)
نظرات مطالب
چگونه نرم افزارهای تحت وب سریعتری داشته باشیم؟ قسمت سوم
کد Razor - کد VB - خروجی SQL
   @(Html.Kendo.Grid(Of Models.vProject).Name("ProjectsGrid") _
        .Columns(Sub(column)
                         With column
                             .Bound(Function(p) p.ProjectId).Hidden()
                             .Bound(Function(p) p.Supervisor).Title("ناظر")
                             .Bound(Function(p) p.MapNumber).Title("شماره نقشه")
                             .Bound(Function(p) p.MapCode).Title("کد نقشه")
                             .Bound(Function(p) p.NewStructureArea).Title("متراژ")
                             .Bound(Function(p) p.NumberOfFloors).Title("تعداد طبقات")
                             .Bound(Function(p) p.InsuranceName).Title("بیمه")
                         End With
                 End Sub).Pageable(Sub(p)
                                           p.Enabled(True)
                                           p.Info(True)
                                           p.PageSizes(True)
                                           p.Messages(Sub(m)
                                                              m.Display("{0} - {1} از {2} رکورد")
                                                              m.Empty("رکوردی برای نمایش وجود ندارد")
                                                              m.Of("از")
                                                              m.Page("صفحه")
                                                              m.ItemsPerPage("رکورد در هر صفحه")
                                                              m.Refresh("بروزرسانی")
                                                      End Sub)
                                   End Sub).Selectable(Sub(s) s.Enabled(True).Mode(GridSelectionMode.Single).Type(GridSelectionType.Row)) _
                                                  .DataSource(Sub(ds) ds.Ajax.ServerOperation(True).Read("GetProjects", "Home") _
                                                                  .Model(Sub(m) m.Id(Function(modelId) modelId.ProjectId)))
    )
 <HttpPost>
        Function GetProjects(<DataSourceRequest> request As DataSourceRequest) As JsonResult
            Return Json(db.vProjects.ToDataSourceResult(request))
        End Function
SELECT TOP (5) [Extent1].[ProjectId]        AS [ProjectId],
               [Extent1].[Supervisor]       AS [Supervisor],
               [Extent1].[MapCode]          AS [MapCode],
               [Extent1].[MapNumber]        AS [MapNumber],
               [Extent1].[EmployerName]     AS [EmployerName],
               [Extent1].[InsuranceName]    AS [InsuranceName],
               [Extent1].[NewStructureArea] AS [NewStructureArea],
               [Extent1].[NumberOfFloors]   AS [NumberOfFloors]
FROM   (SELECT [Extent1].[ProjectId]                                  AS [ProjectId],
               [Extent1].[Supervisor]                                 AS [Supervisor],
               [Extent1].[MapCode]                                    AS [MapCode],
               [Extent1].[MapNumber]                                  AS [MapNumber],
               [Extent1].[EmployerName]                               AS [EmployerName],
               [Extent1].[InsuranceName]                              AS [InsuranceName],
               [Extent1].[NewStructureArea]                           AS [NewStructureArea],
               [Extent1].[NumberOfFloors]                             AS [NumberOfFloors],
               row_number() OVER (ORDER BY [Extent1].[ProjectId] ASC) AS [row_number]
        FROM   (SELECT [vProject].[ProjectId]        AS [ProjectId],
                       [vProject].[Supervisor]       AS [Supervisor],
                       [vProject].[MapCode]          AS [MapCode],
                       [vProject].[MapNumber]        AS [MapNumber],
                       [vProject].[EmployerName]     AS [EmployerName],
                       [vProject].[InsuranceName]    AS [InsuranceName],
                       [vProject].[NewStructureArea] AS [NewStructureArea],
                       [vProject].[NumberOfFloors]   AS [NumberOfFloors]
                FROM   [dbo].[vProject] AS [vProject]) AS [Extent1]) AS [Extent1]
WHERE  [Extent1].[row_number] > 5
ORDER  BY [Extent1].[ProjectId] ASC

اشتراک‌ها
یک Business Apps ساخته شده با Asp.net Core Mvc و , TypeScript

یک CMS تجاری بزرگ با قابلیت‌های زیر

A modular, service based web application model
Code generator to produce initial services / user interface code for an SQL table
T4 based code generation on server to reference script widgets with intellisense / compile time validation
T4 based code generation to provide compile time type safety and intellisense while calling AJAX services from script side.
An attribute based form definition system (prepare UI in server side with a simple C# class)
Automatic seamless data-binding through form definitions (form <-> entity <-> service).
Caching Helpers (Local / Distributed)
Automatic cache validation
Configuration System (storage medium independent. store settings in database, file, whatever...)
Simple Logging
Reporting (reports just provide data, has no dependency on rendering, similar to MVC)
Script bundling, minification (making use of Node / UglifyJS / CleanCSS) and content versioning (no more F5 / clear browser cache)
Fluent SQL Builder (SELECT/INSERT/UPDATE/DELETE)
Micro ORM (also Dapper is integrated)
Customizable handlers for REST like services that work by reusing information in entity classes and do automatic validation.
Attribute based navigation menu
UI Localization (store localized texts in json files, embedded resource, database, in memory class, anywhere)
Data Localization (using an extension table mechanism helps to localize even data entered by users, like lookup tables)
Script widget system (inspired by jQueryUI but more suitable for C# code)
Client side and server side validation (based on jQuery validate plugin, but abstracts dependency)
Audit logging (where CDC is not available)
System for data based integration tests
Dynamic scripts
Script side templates 
یک Business Apps ساخته شده با Asp.net Core Mvc و , TypeScript
نظرات مطالب
NoSQL ؟
- در ravendb امکان replication به sql server وجود دارد.
- یکی از اهداف مهم ORMها در دات نت، نوشتن کوئری‌های strongly typed است. در ravendb شما از روز اول با کوئری‌های strongly typed سروکار دارید. همچنین از همان ابتدای کار هم با کلاس‌های دات نتی و نگاشت خودکار آن‌ها کار می‌کنید. کلا ravendb برمبنای معماری و همچنین توانمندی و پیشرفت‌های زبان‌های دات نتی تهیه شده.

مطالب
آموزش MDX Query - قسمت شانزدهم – استفاده از تابع Filter در MDX Query ها

 در این قسمت بر روی تابع Filter در MDX Query ها تمرکز خواهیم کرد. برای آشنایی با این تابع یک سری از کوئری‌ها را اجرا کرده و به بررسی آنها می‌پردازیم.

Select
{
[Measures].[Internet Sales Amount],
[Measures].[Reseller Sales Amount]
} on columns,
[Product].[Product Categories].[Category] on rows
From [Adventure Works]

دقت کنید که در واکشی، مقدار فروش اینترنتی Component برابر  Null می‌باشد.

Select
{
[Measures].[Internet Sales Amount],
[Measures].[Reseller Sales Amount]
} on columns,
filter(
[Product].[Product Categories].[Category],
[Measures].[Internet Sales Amount] > 0
) on rows
From [Adventure Works]

با توجه به شرطی که اعمال شده است، فقط دسته بندی محصولاتی در خروجی می  آید که فروش اینترنتی آنها بیشتر از صفر  یا برابر Null نباشند.

استفاده از کلید واژه ی  Having  در هر محور کاری شبیه به انجام عمل فیلترینگ می‌ باشد .

Select
{
[Measures].[Internet Sales Amount],
[Measures].[Reseller Sales Amount]
} on columns,
[Product].[Product Categories].[Category]
having [Measures].[Internet Sales Amount] > 0 on rows
From [Adventure Works]

اگر بخواهیم میزان فروش اینترنتی و میزان فروش نمایندگان فروش را برای محصولاتی واکشی کنیم که میزان فروش اینترنتی آنها بیش از 500000 دلار می‌باشد ، کوئری زیر را خواهیم داشت :

Select
{
[Measures].[Internet Sales Amount],
[Measures].[Reseller Sales Amount]
} on columns,
filter(
[Product].[Product Categories].[Category],
[Measures].[Internet Sales Amount] > 500000
  ) on rows
From [Adventure Works]

و برای ایجاد شرط ترکیبی بر روی شاخص، به صورت زیر عمل خواهیم کرد :

Select
{
[Measures].[Internet Sales Amount],
[Measures].[Reseller Sales Amount]
} on columns,
filter(
[Product].[Product Categories].[Category],
[Measures].[Internet Sales Amount] > 500000
and
[Measures].[Internet Sales Amount] < 750000
) on rows
From [Adventure Works]

در مثال بالا، دسته بندی محصولاتی در خروجی واکشی شده اند که میزان فروش اینترنتی آنها بیش از 500 هزار و کمتر از 750 هزار می‌باشد.

استفاده از And , Or در شروط ترکیبی مجاز می‌باشد 

Select
{
[Measures].[Internet Sales Amount],
[Measures].[Reseller Sales Amount]
} on columns,
filter(
[Product].[Product Categories].[Category],
[Measures].[Internet Sales Amount] > 750000
or
[Measures].[Internet Sales Amount] < 500000
  ) on rows
From [Adventure Works]

در زیر با استفاده از And، شرط برروی میزان فروش نمایندگان فروش نیز قرارداده شده است.

Select
{
[Measures].[Internet Sales Amount],
[Measures].[Reseller Sales Amount]
} on columns,
filter(
[Product].[Product Categories].[Category],
(
[Measures].[Internet Sales Amount] > 750000
or
[Measures].[Internet Sales Amount] < 500000
)
and
[Measures].[Reseller Sales Amount] < 15000000
) on rows
From [Adventure Works]

در هنگام ایجاد شروط ترکیبی حتما از ()  استفاده کنید .

حال می‌خواهیم دو شاخص در یک ردیف، با یکدیگر مقایسه شوند و در صورت صحت شرط، آن ردیف در خروجی قرار گیرد

Select
{
[Measures].[Internet Sales Amount],
[Measures].[Reseller Sales Amount]
} on columns,
filter(
[Product].[Product Categories].[Category],
[Measures].[Internet Sales Amount]
>
[Measures].[Reseller Sales Amount]
) on rows
From [Adventure Works]

ایجاد فیلترینگ با استفاده از currentmember  و عملگر  Is .

Select
{
[Measures].[Internet Sales Amount],
[Measures].[Reseller Sales Amount]
} on columns,
filter(
[Product].[Product Categories].[Category],
[Product].[Product Categories].currentmember
is
[Product].[Product Categories].[Category].[Bikes]
) on rows
From [Adventure Works]

البته در  مثال بالا  می توانیم به جای استفاده از Is از = استفاده کنیم. تا اینجا عمل Filtering  برروی شاخص‌ها انجام شده است. اما امکان اعمال Filter روی Dimension ‌ها نیز وجود دارد.

کوئری زیر را بررسی کنید :

Select
{
[Measures].[Internet Sales Amount],
[Measures].[Reseller Sales Amount]
} on columns,
filter(
[Product].[Product Categories].[Category],
[Product].[Product Categories].currentmember
is
[Product].[Product Categories].[Category].[Bikes]
or
[Product].[Product Categories].currentmember
is
[Product].[Product Categories].[Category].[Accessories]
) on rows
From [Adventure Works]

در کوئری بالا میزان فروش نمایندگان فروش و فروش اینترنتی برای دسته بندی‌های Bike  و Accessories واکشی شده است.

امکان ایجاد شرایط ترکیبی از شاخص‌ها و بعد‌ها در یک Filter نیز وجود دارد.

Select
{
[Measures].[Internet Sales Amount],
[Measures].[Reseller Sales Amount]
} on columns,
filter(
[Product].[Product Categories].[Category],
(
[Product].[Product Categories].currentmember
is
[Product].[Product Categories].[Category].[Bikes]
and
[Measures].[Reseller Sales Amount] > 1000000
)
or
(
[Product].[Product Categories].currentmember
is
[Product].[Product Categories].[Category].[Accessories]
)
and
[Measures].[Reseller Sales Amount] > 750000
)on rows
From [Adventure Works]

همچنین می‌توان از Not  درون شرط  Filter  استفاده کرد

Select
{
[Measures].[Internet Sales Amount],
[Measures].[Reseller Sales Amount]
} on columns,
filter(
[Product].[Product Categories].[Category],
not
(
[Product].[Product Categories].currentmember
is
[Product].[Product Categories].[Category].[Clothing]
)
) on rows
From [Adventure Works]

در زیر می‌خواهیم به بررسی تابع non Empty بپردازیم . برای این منظور در ابتدا کوئری زیر را اجرا کنید :

Select
{
[Measures].[Internet Sales Amount],
[Measures].[Reseller Sales Amount]
} on columns,
[Product].[Product Categories].[Subcategory] on rows
From [Adventure Works]

با استفاده از تابع Non Empty، ردیف ‌ها یا ستون هایی حذف می‌ گردند که تمامی مقادیر آن‌ها ، در آن ردیف یا در آن ستون برابر  Null  باشند.

Select
{
[Measures].[Internet Sales Amount],
[Measures].[Reseller Sales Amount]
} on columns,
non empty [Product].[Product Categories].[Subcategory] on rows
From [Adventure Works]

در قسمت آینده برروی توابع Count , Top و ... تمرکز خواهیم کرد.
نظرات مطالب
سیلورلایت 5 و تاریخ شمسی
سلام جناب نصیری
من تو پروژه سیلور از OData استفاده کردم. وقتی می خواستم Max یک ستون رو برگردونم با پیغام زیر مواجه شدم.
.NotSupportedException: The method 'Max' is not supported
ظاهرا بعضی از متدها موقع کوئری نوشتن (LINQ to Entities) با OData و WCF سازگار نیستن و ساپورت نمیشوند.(البته تا جایی که من سرچ کردم و یه چیزایی فهمیدم).
This topic provides information about the way in which LINQ queries are composed and executed when you are using the WCF Data Services client and limitations of using LINQ to query a data service that implements the Open Data Protocol (OData). For more information about composing and executing queries against an OData-based data service, see Querying the Data Service (WCF Data Services).
Composing LINQ Queries
LINQ enables you to compose queries against a collection of objects that implements IEnumerable. Both the Add Service Reference dialog box in Visual Studio and the DataSvcUtil.exe tool are used to generate a representation of an OData service as an entity container class that inherits from DataServiceContext, as well as objects that represent the entities returned in feeds. These tools also generate properties on the entity container class for the collections that are exposed as feeds by the service. Each of these properties of the class that encapsulates the data service return a DataServiceQuery. Because the DataServiceQuery class implements the IQueryable interface defined by LINQ, the WCF Data Services you can compose a LINQ query against feeds exposed by the data service, which are translated by the client library into a query request URI that is sent to the data service on execution.
 Note:
The set of queries expressible in the LINQ syntax is broader than those enabled in the URI syntax that is used by OData data services. A NotSupportedException is raised when the query cannot be mapped to a URI in the target data service. For more information, see the Unsupported LINQ Methods in this topic.
لطفا اگر امکانش هست راهنمائی بفرمائید و اینکه حالا که ساپورت نمیشه چه راه حلی وجود داره برای Max گرفتن.
با تشکر

نظرات مطالب
EF Code First #6
برای هر قابلیتی که در تنظیمات نگاشت‌ها وجود ندارد و سفارشی است باید در تعاریف Migrations در متد Seed آن، SQL مرتبط را ذکر کنید. مانند «ایجاد ایندکس منحصربفرد در EF Code first» و یا «ایندکس منحصر به فرد با استفاده از Data Annotation در EF Code First». اصول و روش کار یکی است؛ فقط کوئری SQL ایی که باید اجرا شود، بنابر نیاز تفاوت می‌کند.
نظرات مطالب
Implementing second level caching in EF code first
بهترین راه جهت تصدیق یا رد کل مطالب عنوان شده استفاده از SQL Server Profiler و مشاهده SQL خروجی است و همچنین شمارش تعداد بار رفت و برگشت به بانک اطلاعاتی (بر اساس حداقل موارد لاگ شده در پروفایلر).
+
کوئری شما فقط یک expression است. هنوز اجرا نشده. اجرای یک عبارت با فراخوانی متدهایی مانند ToList، FirstOrDefault و امثال آن رخ می‌دهد. به این مورد deferred execution گفته می‌شود (قسمت دهم سری ef code first سایت جاری).
نظرات مطالب
آشنایی با NHibernate - قسمت دهم
اول سلام و خسته نباشید
مطالب این orm دنبال کردم و به این نتیجه رسیدم هنر اصلیش در ایجاد کوئری بدون توجه به نوع دیتابیس هستش و خیلی استفاده از رویه های ذخیره شده در sql پیش بینی نشده و این برای برنامه نویس هایی که با sql و sp کار می کنند خوشایند نیست.
و در انتها یک سوال دارم.
جناب نصیری شما خودتون برای لایه دسترسی داده در پروژه شخصی خودتون از چه مودلی استفاده می کنید.