- یک جاب تعریف کن که بازهی اجراش یک ساعت یکبار باشه. هر بار هم که اجرا شد، یک حلقهی 40 تایی رو اجرا کن.
- یک فیلد وضعیت در دیتابیس براش تعریف کن. هر بار که جاب اجرا شد، اول چک کن که این فیلد، فعال بودن یا نبودنش تنظیم شده یا نه.
- یک جاب تعریف کن که بازهی اجراش یک ساعت یکبار باشه. هر بار هم که اجرا شد، یک حلقهی 40 تایی رو اجرا کن.
- یک فیلد وضعیت در دیتابیس براش تعریف کن. هر بار که جاب اجرا شد، اول چک کن که این فیلد، فعال بودن یا نبودنش تنظیم شده یا نه.
using System.Collections.Generic;
namespace EF_Sample08.DomainClasses
{
public class Doctor
{
public int Id { set; get; }
public string Name { set; get; }
public virtual ICollection<Patient> Patients { set; get; }
}
}
namespace EF_Sample08.DomainClasses
{
public class Patient
{
public int Id { set; get; }
public string Name { set; get; }
public virtual Doctor Doctor { set; get; }
}
}
using System.Data.Entity;
using EF_Sample08.DomainClasses;
namespace EF_Sample08.DataLayer.Context
{
public class Sample08Context : DbContext
{
public DbSet<Doctor> Doctors { set; get; }
public DbSet<Patient> Patients { set; get; }
}
}
using System.Data.Entity.Migrations;
using EF_Sample08.DomainClasses;
using System.Collections.Generic;
namespace EF_Sample08.DataLayer.Context
{
public class Configuration : DbMigrationsConfiguration<Sample08Context>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
protected override void Seed(Sample08Context context)
{
addData(context);
addSP(context);
addFn(context);
base.Seed(context);
}
private static void addData(Sample08Context context)
{
var patient1 = new Patient { Name = "p1" };
var patient2 = new Patient { Name = "p2" };
var doctor1 = new Doctor { Name = "doc1", Patients = new List<Patient> { patient1, patient2 } };
context.Doctors.Add(doctor1);
}
private static void addFn(Sample08Context context)
{
context.Database.ExecuteSqlCommand(
@"IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[FindDoctorPatientsCount]')
AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[FindDoctorPatientsCount]");
context.Database.ExecuteSqlCommand(
@"CREATE FUNCTION FindDoctorPatientsCount(@Doctor_Id INT)
RETURNS INT
BEGIN
RETURN
(
SELECT COUNT(*)
FROM Patients
WHERE Doctor_Id = @Doctor_Id
);
END");
}
private static void addSP(Sample08Context context)
{
context.Database.ExecuteSqlCommand(
@"IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[FindDoctorsStartWith]')
AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[FindDoctorsStartWith]
");
context.Database.ExecuteSqlCommand(
@"CREATE PROCEDURE FindDoctorsStartWith(@name NVARCHAR(400))
AS
SELECT *
FROM Doctors
WHERE [Name] LIKE @name + '%'");
}
}
}
using System;
using System.Data;
using System.Data.Entity;
using System.Data.Objects.SqlClient;
using System.Data.SqlClient;
using System.Linq;
using EF_Sample08.DataLayer.Context;
using EF_Sample08.DomainClasses;
namespace EF_Sample08
{
class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<Sample08Context, Configuration>());
using (var db = new Sample08Context())
{
runSp(db);
runFn(db);
usingSqlFunctions(db);
}
}
private static void usingSqlFunctions(Sample08Context db)
{
var doctorsWithNumericNameList = db.Doctors.Where(x => SqlFunctions.IsNumeric(x.Name) == 1).ToList();
if (doctorsWithNumericNameList.Any())
{
//do something
}
}
private static void runFn(Sample08Context db)
{
var doctorIdParameter = new SqlParameter
{
ParameterName = "@doctor_id",
Value = 1,
SqlDbType = SqlDbType.Int
};
var patientsCount = db.Database.SqlQuery<int>("select dbo.FindDoctorPatientsCount(@doctor_id)", doctorIdParameter).FirstOrDefault();
Console.WriteLine(patientsCount);
}
private static void runSp(Sample08Context db)
{
var nameParameter = new SqlParameter
{
ParameterName = "@name",
Value = "doc",
Direction = ParameterDirection.Input,
SqlDbType = SqlDbType.NVarChar
};
var doctors = db.Database.SqlQuery<Doctor>("exec FindDoctorsStartWith @name", nameParameter).ToList();
if (doctors.Any())
{
foreach (var item in doctors)
{
Console.WriteLine(item.Name);
}
}
}
}
}
db.Database.SqlQuery<Doctor>("exec FindDoctorsStartWith "+ txtName.Text, nameParameter).ToList()
فرض کنید که میخواهیم یک برنامه برای یک فروشگاه نوشیدنی (مانند coffee shop) بنویسیم ، این فروشگاه در ابتدای کار ممکن است ، منوی سادهای جهت ارائه به مشتری داشته باشد. برای مثال ممکن است که فقط 3 یا 4 محصول داشته باشد. بنابراین ممکن است ما برنامهای را که میخواهیم برای این مشتری بنویسیم به صورت زیر طراحی کنیم:
که بسیار طبیعی و درست میباشد. اما حالا در نظر بگیرید که این فروشگاه در آینده ممکن است محصولات خود را افزایش بدهد و یا حالاتی که ممکن است این محصولات با هم ادغام شوند را در نظر بگیرید. برای مثال ممکن است شما بخواهید که قهوهتان را با شیر نوش جان کنید و یا ....
بنابراین تعداد این حالات را در نظر بگیرید که در آینده ممکن است چقدر زیاد بشود:
خوب پس چهکاری ما میتوانیم برای نگهداری این برنامه انجام بدهیم؟ یکی از راههایی که ممکن است به فکر ما برسد این است که روش بالا روش احمقانه ای است. چرا ما باید به همهی این کلاسها نیاز داشته باشیم. ما میتوانیم که چاشنیها را در کلاس اصلی نگهداری کنیم و کلاس محصولاتمان را از کلاس اصلی به ارث ببریم اجازه دهید تا این کار را با هم انجام بدهیم
خوب با این روش ما n کلاس تشکیل شده در رویکرد اول را فقط به 5 کلاس تبدیل کردیم. خوب این روشی بسیار ایدهال به نظر میرسد. اما ممکن است در آینده که تعداد چاشنیهای ما بالا میرود و همچنین تعداد محصولاتمان نیز ممکن است بیشتر شود مجبور شویم که تعداد این کلاسها را بیشتر کنیم، و یا فکر کنید که ما میخواهیم هریک از چاشنیهایمان، یک قیمت را نسبت بدهیم. بنابراین مجبوریم که تمامی اینها را در کلاس پایه اضافه کنیم؛ بله درست است، ما با کلاس پایهی حجیمی روبرو میشویم که بیشتر خواص و یا متدهای آن برای زیر کلاسهای دیگر مناسبت نیستند. خوب آیا روش بهتری برای جلوگیری از این مشکل داریم؟ بلی.
خوب ما به این مسئله به این صورت نگاه میکنیم که شروع میکنیم با نوشیدنیها و آنها را با چاشنیها در زمان اجرا تزیین (Decorate) میکنیم؛ نه کامپایل.
برای مثال اگر مشتری ما یک نوشیدنی DarkRoast با Mocha و Whip خواست، سپس ما :
1- یک شی از DarkRoast ایجاد میکنیم .
2- آن را با یک شی از Mocha تزئین میکنیم.
3- آن را با یک شی از Whip - تزیین میکنیم.
4- متد Cost() را صدا میزنیم و یک Delegation را برای اضافه کردن قیمت چاشنیها در نظر میگیریم.
بسیار خوب؛ اما ما عملیات تزئین یک شی را چگونه انجام میدهیم و delegation ما چگونه عمل میکند .
یک اشاره : به شیء تزئین کننده، مانند یک Wrappers فکر کنید. اجاز بدهید ببینم که چه طور این کار را انجام میدهیم.
1- یک شی از DarkRoast ایجاد میکنیم.
3- آن را با یک شی از Whip تزیین میکنیم
4- حالا زمان محاسبه قیمت محصول برای مشتری فرا رسیده است. ما این کار را را با صدا زدن بیرونیترین Decorator(Whip) انجام میدهیم و شی whip به کمک Delegate مابقی توابع cost را صدا میزند.
public abstract class Beverage { string description ="unknow beverage"; public String getDescription(){ return description; } public abstract double cost(); } public abstract class CondimentDecorator extends Beverage { public abstract string getDescription(); } public class Espersso extends Beverage{ public Espersso() { description="Espersso"; } public double cost(){ return 1.99; } } public class HouseBelend extends Beverage { public HouseBelend() { description="HouseBelend"; } public double cost() { return .89; } } public class mocha extends condimateDecorator { Beverage beverage; public mocha(Beverage beverage) { this.beverage=beverage; } public string getDescription(){ return beverage.getdescription() + "Mocha"; } public double cost(){ return .20 +beverage.cost } } // Now Use These classes in Final form Beverage beverage=new Espersso(); //Customers want a coffe with double milk and whip beverage=new mocha(beverage); beverage=new mocha(meverage); beverage=new whip(beverage); system.out.println(beverage.getDescription() + "$" +beverage.cost());
طراحی فایل MRT
فایل MRT در واقع یک قالب (Template) خالی از مقادیر متغیر است که در StimulSoft Studio به طراحی آن میپردازیم و در برنامه خود، این مقادیر متغیر را با اطلاعات دلخواه خود جایگزین میکنیم. تصویر زیر یک نمونه از یک گزارش خالی است که ابتدا آن را طراحی کرده و سپس در برنامه آن را مورد استفاده قرار میدهیم:
برای اینکه فایل MRT بتواند دیتاهای لازمی را که به آن پاس میدهیم، بخواند و در جای مشخص شده قرار بدهد، باید یک BussinessObject برای آن ایجاد کنیم. بعد از اینکه یک گزارش جدید ایجاد کردید، در سمت راست به قسمت Dictionary بروید و در قسمت BussinessObject گزینه NewBussinessObject را انتخاب کنید. یک نام و نام مستعار که عموما هم یکی است، برای آن انتخاب کنید. در زیر همان پنجره شما میتوانید ستونهای اطلاعاتی خود را تعریف کنید. در اینجا من میخواهم اطلاعات یک راننده را به همراه خودروی وی، نشان دهم. برای همین، من دو موجودیت راننده و خودروی راننده را دارم. پس اسم Business Object را DriverReport میگذارم و ستونهای اطلاعاتی فقط راننده (بدون در نظر گرفتن خودروی وی) را وارد میکنم.
در همین کادر بالا شما میتوانید تصیم بگیرید که آیا میخواهید اطلاعات خودرو را به همراه دیگرستونهای اطلاعاتی راننده، ایجاد کنید یا اینکه برای خودرو یک نوع مجزا انتخاب کنید. اگر تنها یک خودرو برای راننده باشد، شاید راحتتر باشید همانند اطلاعات راننده با آن رفتار کنید. ولی اگر مثلا بخواهید خودرویهای گذشته راننده را هم جز لیست داشته باشید، بهتر است یک Business Object جدید متعلق و زیر مجموعه Business Object راننده ایجاد کنید. در اینجا چون تنها یک خودرو است، من آن اطلاعات آن را به همراه راننده، ارسال میکنم. شکل زیر ساختار درختی از گزارش بالاست:
شکل زیر هم یک ساختار دیگر از یک گزارش است که شامل Business objectهای مختلف میشود:
سپس همین فیلدها را به سمت صفحه خالی بکشانید. با دو بار کلیک روی فیلدهای قرار گرفته در صفحه، با نحوه بایند کردن مقادیر آشنا میشوید؛ هر فیلدی که قرار است دیتای آن بایند شود، باید به شکل زیر در بخش Expression پنجره باز شده، نوشته شود:
{driverReport.LastName}
راه اندازی گزارش ساز در ASP.Net MVC
اولین کاری که میکنیم، ورود سه dll اصلی به پروژه است:
Stimulate.Base
Stimulate.Report
Stimulate.Report.MVC
در مرحله بعد یک متد ساخته و یک ویوو را برای صفحه گزارش گیری ایجاد میکنیم:
public ActionResult Report(int id) { return View(); }
@Html.Stimulsoft().StiMvcViewer(new StiMvcViewerOptions() { Localization = "~/content/reports/fa.xml", Actions = { GetReportSnapshot = "LoadReportSnapshot", ViewerEvent = "ViewerEvent", ExportReport = "ExportReport", PrintReport = "PrintReport", } }
@Html.Stimulsoft().StiMvcViewer(new StiMvcViewerOptions() { Localization = "~/content/reports/fa.xml", ActionGetReportSnapshot = "LoadReportSnapshot", ActionViewerEvent = "ViewerEvent", ActionExportReport = "ExportReport", ActionPrintReport = "PrintReport", }
var driver = new { FirstName = "علی", LastName = "یگانه مقدم", NationalCode = "12500000000", FatherName = "حسین", Model = "نام خودرو", MotorNumber = 415244, ProductionYear = 1394, Capacity = 4 };
var driver = new { FirstName = "علی", LastName = "یگانه مقدم", NationalCode = "12500000000", FatherName = "حسین", car = new { Model = "نام خودرو", MotorNumber = 415244, ProductionYear = 1394, Capacity = 4 } };
var report = new StiReport(); report.Load(Server.MapPath("~/Content/Reports/driver.mrt")); report.RegBusinessObject("driverReport", driver); report.Dictionary.Variables.Add("today", DateTime.Today.ToPersianString(PersianDateTimeFormat.Date));
var report = new StiReport(); report.RegBusinessObject("driverReport", driver); report.Dictionary.Variables.Add("today", DateTime.Today.ToPersianString(PersianDateTimeFormat.Date)); report.Load(Server.MapPath("~/Content/Reports/driver.mrt"));
public ActionResult LoadReportSnapshot() { var driver = new { FirstName = "علی", LastName = "یگانه مقدم", NationalCode = "12500000000", FatherName = "حسین", Model = "نام خودرو", MotorNumber = 415244, ProductionYear = 1394, Capacity = 4 }; var report = new StiReport(); report.Load(Server.MapPath("~/Content/Reports/driver.mrt")); report.RegBusinessObject("driverReport", driver); report.Dictionary.Variables.Add("today", DateTime.Today.ToPersianString(PersianDateTimeFormat.Date)); return StiMvcViewer.GetReportSnapshotResult(HttpContext, report); }
public virtual ActionResult ViewerEvent() { return StiMvcViewer.ViewerEventResult(); }
public virtual ActionResult PrintReport() { return StiMvcViewer.PrintReportResult(this.HttpContext); }
public virtual ActionResult ExportReport() { return StiMvcViewer.ExportReportResult(this.HttpContext); }
.stiMvcViewerReportPanel table{ direction:ltr !important; }
حال حتما پیش خود میگویید که این روش برای اطلاعات ایستا و تمرینی مناسب است و من چگونه باید پارامترهای ارسالی به اکشن متد Report را به اکشن متد LoadReportSnapshot ارسال کنم. برای این منظور استفاده از SessionStateها زیاد توصیه شدهاست:
public virtual ActionResult Report(int id) { TempData["id"]=id; return View(); } public virtual ActionResult LoadReportSnapshot() { var driverId = (int)TempData ["id"]; //..... }
public virtual ActionResult Report(int id) { return View(); } public virtual ActionResult LoadReportSnapshot(int id) { //..... }
Server = { GlobalReportCache = false }
حجم زیاد اطلاعات، مدیران مجموعهها را در تحلیل و یافتن اطلاعات مفید دچار چالش کرده است. داده کاوی، ابزار مناسب برای تجزیه و تحلیل اطلاعات و کشف و استخراج روابط پنهان در مجموعههای دادهای سنگین را فراهم میکند. گروه مشاورهای گارتنر داده کاوی را استخراج نیمه اتوماتیک الگوها، تغییرات، وابستگیها، نابهنجاریها و دیگر ساختارهای معنی دار آماری از پایگاههای بزرگ داده تعریف میکند. داده کاوی، تلاشی برای یافتن قوانین، الگوها و یا میل احتمالی داده به مُدلی، در بین انبوهی از دادهها است.
داده کاوی فرآیندی پیچیده جهت شناسایی الگوها و مدلهای صحیح، جدید و به صورت بالقوه مفید، در حجم وسیعی از داده میباشد؛ به طریقی که این الگوها و مدلها برای انسانها قابل درک باشند. داده کاوی به صورت یک محصول قابل خریداری نمیباشد، بلکه یک رشته علمی و فرآیندی است که بایستی به صورت یک پروژه پیاده سازی شود.
به بیانی دیگر داده کاوی، فرآیند کشف الگوهای پنهان، جالب توجه، غیر منتظره و با ارزش از داخل مجموعه وسیعی از دادههاست و فعالیتی در ارتباط با تحلیل دقیق دادههای سنگین بی ساختار است که علم آمار ناتوان از تحلیل آنهاست. بعضی مواقع دانش کشف شده توسط داده کاوی عجیب به نظر میرسد؛ مثلا ارتباط افراد دارای کارت اعتباری و جنسیت با داشتن دفترچه تامین اجتماعی یا سن، جنسیت و درآمد اشخاص با پیش بینی خوش حسابی او در بازپرداخت اقساط وام. داده کاوی در حوزههای تصمیم گیری، پیش بینی، و تخمین مورد استفاده قرار میگیرد.
پایه و اساس این تکنیک، ریشه در علوم زیر دارد:
OLAP و داده کاوی فن آوریهای تحلیلی در خانواده BI به شمار میآیند. OLAP در زمینه تجمیع مقادیر عظیم دادههای تراکنشی بر پایه تعاریف ابعادی مناسب است.
فن آوری OLAP بر پایه محاسبات تجمیعی است. سرویس دهنده OLAP نوع خاصی از سرویس دهندهی بانک اطلاعاتی محسوب میگردد که با دادههای چند بعدی سروکار دارد. بسیاری از مشکلات و مخاطرات نظیر ایندکس گذاری، ذخیره سازی دادهها و ... که در RDBMSها وجود دارد در سرویس دهندهی OLAP نیز وجود دارد.
داده کاوی در یافتن الگوهای پنهان از یک مجموعه داده توسط تحلیل همبستگی میان مقادیر مشخصهها مناسب است.
تکنیکهای داده کاوی دو گونه هستند: نظارت شده و نظارت نشده. در داده کاوی نظارت شده کاربر میبایست مشخصهی هدف و مجموعه دادهی ورودی را تعیین نماید. الگوریتمهای داده کاوی نظارت شده شامل درخت تصمیم، نیو بیز و شبکههای عصبی هستند. تکنیکهای داده کاوی نظارت نشده نیازی به تعیین مشخصهی قابل پیش بینی ندارد. خوشه بندی مثال خوبی از داده کاوی نظارت نشده میباشد و به گروه بندی نقاط داده ای ناهمگن به زیر گروه هایی میپردازد که در آنها نقاط داده ای کم و بیش مشابه و همگن هستند.
یکی از فرآیندهای اصلی داده کاوی، تحلیل همبستگی میان مشخصهها و مقادیر آنها است. محققین آمار در این موارد قرنها مطالعه داشتهاند. OLAP و داده کاوی دو فن آوری مختلف هستند اما فعالیتهای یکدیگر را تکمیل میکنند. OLAP فعالیت هایی نظیر خلاصه سازی، تحلیل تغییرات در طول زمان و تحلیلهای What If را پشتیبانی مینماید. همچنین میتوان آنرا برای تحلیل نتایج داده کاوی در سطوح مختلف و مجزا استفاده کرد. داده کاوی نیز میتواند در ساخت Cubeهای مفیدتر سودمند باشد.
تفاوت میان OLAP و داده کاوی ارتباطی به تفاوت میان دادههای تلخیص شده و دادههای تشریحی ندارد. در واقع تمایز قابل توجهی میان مدل سازی توصیفی و تشریحی وجود دارد. توابع و الگوریتم هایی که معمولاً در ابزارهای OLAP یافت میشود، توابع مدل سازی توصیفی به شمار میآیند. در حالیکه توابعی که در آنچه که اصطلاحاً بسته داده کاوی نامیده میشود، یافت میشود توابع یا الگوهای مدل سازی تشریحی هستند.
این الگوریتمها را به 5 دسته تقسیم میتوان نمود:
برای مثال جهت تجزیه و تحلیل مجموعه ای از شرایط آب و هوایی که منجر به وقوع پدیده خاصی میشود. از الگوریتم زیر استفاده میشود:
Microsoft Sequence Clustering Algorithm
Microsoft Association Algorithm
Microsoft Decision Trees Algorithm
Microsoft Clustering Algorithm
Microsoft Sequence Clustering Algorithm
Microsoft Decision Trees Algorithm
Microsoft Naive Bayes Algorithm
Microsoft Clustering Algorithm
Microsoft Neural Network Algorithm
Microsoft Decision Trees Algorithm
Microsoft Time Series Algorithm