18. Declare variables as close as possible to where it is first used. Use one variable declaration per line.
ماخذ:
http://www.dotnetspider.com/tutorials/CodingStandards.doc
Select { [Measures].[Internet Sales Amount], [Measures].[Internet Tax Amount] } on columns, head( [Customer].[Customer Geography].[Country], 2 )on rows From [Adventure Works]
تابع Head، تعداد مشخص شده بر اساس پارامتر اول از آن محور را بر اساس نحوهی نمایش تنظیم شده در SSAS، واکشی میکند.
حال تصور کنید بخواهیم شرط زیر را بر روی کوئری بالا اجرا کنیم
( [Measures].[Internet Sales Amount] >= '2500000' )
به عبارت دیگر ما میخواهیم دو کشوری را انتخاب کنیم که میزان فروش اینترنتی آنها بالای 2500000 باشد.
کوئری مشابه زیر میباشد
Select { [Measures].[Internet Sales Amount], [Measures].[Internet Tax Amount] } on columns, head( [Customer].[Customer Geography].[Country], 2 )on rows From [Adventure Works] Where ( [Measures].[Internet Sales Amount] >= '2500000' )
البته خطای زیر را خواهیم داشت.
به یاد داشته باشیم در صورتیکه بخواهیم ایجاد محدودیت در نمایش دادهها را در یک محور داشته باشیم، باید از تابع Filter استفاده کنیم؛ به صورت زیر:
Select Filter( { [Measures].[Internet Sales Amount], [Measures].[Internet Tax Amount] } , [Measures].[Internet Sales Amount] >= 2644017.71 ) on columns, head( [Customer].[Customer Geography].[Country], 3 )on rows From [Adventure Works]
تابع Filter دو پارامتر می گیرد. پارامتر اول نام ردیف یا ستونی می باشد که روی آن می خواهیم عمل فیلتر را انجام دهیم. پارامتر دوم شرط فیلترینگ می باشد که می بایست مانند T/SQL دارای یک خروجی Boolean باشد
همچنان نتیجه درست نمیباشد ! چرا؟
اگر بخواهیم شرط روی Axis ردیف (کشور ها) اعمال گردد، باید عملیات فیلترینگ در این Axis انجام شود . بنابر این خروجی بدست آمده صحیح نمی باشد زیرا ما عملیات فیلترینگ را روی ستون ها انجام داده ایم.
کوئری زیر را اجرا نمایید
Select { [Measures].[Internet Sales Amount] ,[Measures].[Internet Tax Amount] } on columns, head( Filter( [Customer].[Customer Geography].[Country] , [Measures].[Internet Sales Amount] >= 2644017.71 ), 3) on rows From [Adventure Works]
البته توجه کنید که این کوئری، سه کشور اول که در شرط زیر قرار دارند را بر می گرداند و الزاما این سه کشور از تمام کشور های دیگر بیشتر نمی باشند.
در این حالت سه کشور که بالاتر از مقدار ذکر شده، فروش اینترنتی دارند، در خروجی قرار می گیرند . البته این سه کشور دارای بالاترین فروش نمی باشند بلکه به ترتیب اسم، از بالا گزینش انجام شده است و بعد از پیدا کردن سه کشور که در شرط قرار بگیرند، جستجو تمام شده است .
اگر بخواهیم سه کشوری را که بالاترین میزان فروش را دارند پیدا کنیم و شرط هم همواره اعمال گردد، کوئری زیر درست می باشد:
Select { [Measures].[Internet Sales Amount] ,[Measures].[Internet Tax Amount] } on columns, TopCount( Filter( [Customer].[Customer Geography].[Country] , [Measures].[Internet Sales Amount] >= 2644017.71 ), 3, [Measures].[Internet Sales Amount]) on rows From [Adventure Works]
در این حالت به جای تابع Head از تابع TopCount استفاده گردیده است .این تابع سه کشوری را که بیشترین فروش اینترنتی را داشته اند و این فروش بالاتر از مقدار ذکر شده در شرط می باشد را بر می گرداند .البته در اینجا تابع topcount دارای سه پارامتر می باشد و در پارامتر سوم اعلام میکند که تعداد بالای مجموعه براساس چه شاخصی باید به دست بیاید.
حال اگر بخواهیم سه ردیف انتهایی جدول را واکشی کنیم داریم:
Select { [Measures].[Internet Sales Amount], [Measures].[Internet Tax Amount] }on columns, tail([Customer].[Customer Geography].[Country], 3)on rows From [Adventure Works]
این تابع برعکس تابع Head کار میکند و N ردیف آ اخر مجموعه را بدست می آورد . البته در بالا فقط 3 ردیف انتهایی را
در خروجی آورده ایم و هیچ شرطی اعمال نگردیده است.
<PropertyGroup> <TargetFramework>netcoreapp1.1</TargetFramework> <TypeScriptCompileBlocked>true</TypeScriptCompileBlocked> </PropertyGroup>
<ItemGroup> <Folder Include="Controllers\" /> <Folder Include="wwwroot\" /> </ItemGroup> <ItemGroup> <Compile Remove="node_modules\**" /> <Content Remove="node_modules\**" /> <EmbeddedResource Remove="node_modules\**" /> <None Remove="node_modules\**" /> </ItemGroup> <ItemGroup> <Compile Remove="src\**" /> <Content Remove="src\**" /> <EmbeddedResource Remove="src\**" /> </ItemGroup>
<ItemGroup> <PackageReference Include="Microsoft.AspNetCore" Version="1.1.1" /> <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" /> <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.1" /> </ItemGroup> <ItemGroup> <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.0" /> </ItemGroup> <ItemGroup> <!-- extends watching group to include *.js files --> <Watch Include="**\*.js" Exclude="node_modules\**\*;**\*.js.map;obj\**\*;bin\**\*" /> </ItemGroup>
using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; namespace ASPNETCoreIntegrationWithAngularCLI.Controllers { [Route("api/[controller]")] public class ValuesController : Controller { // GET: api/values [HttpGet] [ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)] public IEnumerable<string> Get() { return new string[] { "Hello", "DNT" }; } } }
using System; using System.IO; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace ASPNETCoreIntegrationWithAngularCLI { public class Startup { public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.Use(async (context, next) => { await next(); if (context.Response.StatusCode == 404 && !Path.HasExtension(context.Request.Path.Value) && !context.Request.Path.Value.StartsWith("/api/", StringComparison.OrdinalIgnoreCase)) { context.Request.Path = "/index.html"; await next(); } }); app.UseMvcWithDefaultRoute(); app.UseDefaultFiles(); app.UseStaticFiles(); } } }
>ng new ClientApp --routing --skip-install --skip-git --skip-commit
"apps": [ { "root": "src", "outDir": "wwwroot",
import { Component, OnInit } from '@angular/core'; import { Http } from '@angular/http'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { constructor(private _httpService: Http) { } apiValues: string[] = []; ngOnInit() { this._httpService.get('/api/values').subscribe(values => { this.apiValues = values.json() as string[]; }); } }
<h1>Application says:</h1> <ul *ngFor="let value of apiValues"> <li>{{value}}</li> </ul> <router-outlet></router-outlet>
> ng build --watch
<Target Name="AngularBuild" AfterTargets="Build"> <Exec Command="ng build" /> </Target>
> dotnet watch run
>dotnet watch run [90mwatch : [39mStarted Hosting environment: Production Now listening on: http://localhost:5000 Application started. Press Ctrl+C to shut down.
{ "/api": { "target": "http://localhost:5000", "secure": false } }
>ng serve --proxy-config proxy.config.json -o
<ItemGroup> <PackageReference Include="Microsoft.AspNetCore.Diagnostics" Version="1.1.1" />
که الگوریتم پیش فرض نرمال سازی آنها که فقط to upper case است، قابلیت سفارشی سازی هم دارد (برای مثال جهت اعمال نکات مطلب فوق).
protected void Application_Start() { //... Database.SetInitializer(...همانند سابق...); using (var context = new MyContext()) { context.Database.Initialize(force: true); } //... }
سیستم ASP.NET Membership بهمراه ASP.NET 2.0 در سال 2005 معرفی شد، و از آن زمان تا بحال تغییرات زیادی در چگونگی مدیریت احزار هویت و اختیارات کاربران توسط اپلیکیشنهای وب بوجود آمده است. ASP.NET Identity نگاهی تازه است به آنچه که سیستم Membership هنگام تولید اپلیکیشنهای مدرن برای وب، موبایل و تبلت باید باشد.
پروژه ایجاد شده شامل سه بسته میشود که مربوط به ASP.NET Identity هستند:
هنگامیکه بر روی دکمهی Register کلیک شود، کنترلر Account، اکشن متد Register را فراخوانی میکند تا حساب کاربری جدیدی با استفاده از ASP.NET Identity API ساخته شود.
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new ApplicationUser() { UserName = model.UserName }; var result = await UserManager.CreateAsync(user, model.Password); if (result.Succeeded) { await SignInAsync(user, isPersistent: false); return RedirectToAction("Index", "Home"); } else { AddErrors(result); } } // If we got this far, something failed, redisplay form return View(model); }
اگر حساب کاربری با موفقیت ایجاد شود، کاربر توسط فراخوانی متد SignInAsync به سایت وارد میشود.
[HttpPost] [AllowAnonymous] [ValidateAntiForgeryToken] public async Task<ActionResult> Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new ApplicationUser() { UserName = model.UserName }; var result = await UserManager.CreateAsync(user, model.Password); if (result.Succeeded) { await SignInAsync(user, isPersistent: false); return RedirectToAction("Index", "Home"); } else { AddErrors(result); } } // If we got this far, something failed, redisplay form return View(model); }
private async Task SignInAsync(ApplicationUser user, bool isPersistent) { AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie); var identity = await UserManager.CreateIdentityAsync( user, DefaultAuthenticationTypes.ApplicationCookie); AuthenticationManager.SignIn( new AuthenticationProperties() { IsPersistent = isPersistent }, identity); }
از آنجا که ASP.NET Identity و OWIN Cookie Authentication هر دو Claims-based هستند، فریم ورک، انتظار آبجکتی از نوع ClaimsIdentity را خواهد داشت. این آبجکت تمامی اطلاعات لازم برای تشخیص هویت کاربر را در بر دارد. مثلا اینکه کاربر مورد نظر به چه نقش هایی تعلق دارد؟ و اطلاعاتی از این قبیل. در این مرحله میتوانید Claimهای بیشتری را به کاربر بیافزایید.
کلیک کردن روی لینک Log off در سایت، اکشن متد LogOff در کنترلر Account را اجرا میکند.
// POST: /Account/LogOff [HttpPost] [ValidateAntiForgeryToken] public ActionResult LogOff() { AuthenticationManager.SignOut(); return RedirectToAction("Index", "Home"); }
همانطور که مشاهده میکنید برای ورود/خروج کاربران از AuthenticationManager استفاده میشود که متعلق به OWIN است. متد SignOut همتای متد FormsAuthentication.SignOut است.
تصویر زیر اجزای تشکیل دهنده ASP.NET Identity را نمایش میدهد. بسته هایی که با رنگ سبز نشان داده شده اند سیستم کلی ASP.NET Identity را میسازند. مابقی بستهها وابستگی هایی هستند که برای استفاده از ASP.NET Identity در اپلیکیشنهای ASP.NET لازم اند.
دو پکیج دیگر نیز وجود دارند که به آنها اشاره نشد: