مطالب
آشنایی با قابلیت جدید ASP.NET Web Forms Scaffolding
مایکروسافت با افزایش سرعت به روز رسانی توسعه پروژه‌های سورس باز خود جهت پاسخ دادن به نیاز توسعه دهندگان و توسعه ویژوال استادیو مطابق با آخرین تکنولوژی‌های تولید وب سایت، می‌کوشد تعداد بیشتری از توسعه دهندگان را به سمت استفاده از تکنولوژی‌های خود سوق دهد. 

سالها است که برنامه نویسان خبره با توجه به روش کاری خود از امکانات Code Generatorها برای تولید کدهای لایه‌های Data Access ، Logic و یا حتی User Interface استفاده می‌نمایند. پس از عرضه Entity Framework و تولید خودکار کدهای لایه های Data Access و Logic، این بار این امکان علاوه بر ASP.NET MVC در ASP.NET Web Forms نیز فراهم گردیده‌است تا بدون کد نویسی خسته کننده و تکراری، کدهای لایه رابط کاربر (Create-Read-Update-Delete (CRUD را نیز تولید نماییم. 

شروع کار با ASP.NET Scaffolding
پیش نیاز این کار استفاده از Visual Studio 2012 به همراه Web Tools 2012.2 می‌باشد.
  1. اول، ابزار Microsoft ASP.NET Scaffolding را از منوی Tools گزینه Extensions and Updates دریافت و نصب نمایید.
  2. دوم پروژه جدیدی از نوع Visual C# ASP.NET Web Forms Application با فریم ورک 4.5 ایجاد نمایید.
  3. از پنجره NuGet Package manager با دستور install کتابخانه ASP.NET Web Forms Scaffold Generator را دریافت نمایید
    install-package Microsoft.AspNet.Scaffolding.WebForms -pre
  4. کلاس Person را مانند زیر در فولدر Models ایحاد نمایید
     public class Person
        {
            [ScaffoldColumn(false)]
            public int ID { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
        }
    ویژگی ScaffoldColumn را برای ID، برابر false قرار دهید تا از ایجاد این ستون جلوگیری نمائید.
  5. پروژه را Build نمایید.
  6. بر روی پروژه راست کلیک و از گزینه Add، گزینه ...Scaffold را انتخاب نمایید.

  7. از پنجره Add Scaffold باز شده بر روی گزینه Add، کلیک کنید.

  8. پنجره  Add Web Forms Pages مانند زیر باز می‌شود که امکان انتخاب کلاس،Data Context و MasterPage فراهم می‌باشد.

  9. از گزینه Data Context class گزینه New Data Context را انتخاب نمایید. صفحات مورد نیاز را در فولدر Views/Person ایجاد می‌نمایید.
  10. کد‌های تولید شده را می‌توانید بازبینی نمایید پروژه را اجرا تا خروجی کار را مشاهده نمایید.

نظرات مطالب
نحوه تهیه گزارش در SSRS و انتشار آن روی وب سرور
به هیچ وجه، انطباق خوب یک ابزار با یک پایگاه داده ازطریق SQL یک اشکال محسوب نمیشه !
منظورتون از برقراری ارتباط بین EF و SSRS اینه که data source  انتخابی برای SSRS رو EF انتخاب کنیم ؟  
اگر بله؛  دلیله این  کار چیه که از یک سو EF به SQL وصل بشه و از طرفی هم به SSRS... مستقیم این ارتباط رو برقرار می‌کنیم... (یعنی SSRS به SQL و با همان دستورات بدون نیاز به وجود واسطه ای به نام EF)
هر ابزاری را با هدف خاصی پیاده سازی می‌کنند و اصلا دلیلی نداره که انتظار برقراری از طریق EF با SSRS وجود داشته باشه ! EF برای یک مقیاس و کاربرد استفاده میشه و SSRS برای یک مقیاس و کاربرد دیگر.
و اگر نه، ممکنه بیشتر توضیح بدید؟
اشتراک‌ها
EF Core 5.0 Preview 8 منتشر شد

Today, the Entity Framework Core team announces the eighth and final preview release of EF Core 5.0. The next release will be a release candidate (RC). This release includes table-per-type (TPT) mapping, table-valued functions, SQLite table rebuilds for migrations and much more. 

EF Core 5.0 Preview 8 منتشر شد
نظرات مطالب
ایجاد سرویس چندلایه‎ی WCF با Entity Framework در قالب پروژه - 7
با سلام؛ قبل از هر چیز ممنون از آموزش خوبتون. یک سوال در رابطه با قسمت اول این آموزش داشتم. من دقیقا با آموزش شما پیش رفتم و در قسمت هفتم آموزشتون در اجرای پروژه دچار مشکل شدم و در مرورگرم با خطای زیر مواجه شدم:
HTTP Error 403.14 - Forbidden
The Web server is configured to not list the contents of this directory.
Most likely causes:

    A default document is not configured for the requested URL, and directory browsing is not enabled on the server.

Things you can try:

    If you do not want to enable directory browsing, ensure that a default document is configured and that the file exists.
    Enable directory browsing using IIS Manager.
        Open IIS Manager.
        In the Features view, double-click Directory Browsing.
        On the Directory Browsing page, in the Actions pane, click Enable.
    Verify that the configuration/system.webServer/directoryBrowse@enabled attribute is set to true in the site or application configuration file.

Detailed Error Information:
Module DirectoryListingModule
Notification ExecuteRequestHandler
Handler StaticFile
Error Code 0x00000000
Requested URL http://localhost:80/3724/
Physical Path C:\inetpub\wwwroot\3724\
Logon Method Anonymous
Logon User Anonymous
مطالب
استفاده از DbProviderFactory
استفاده از DbProviderFactory امکان اتصال به دیتابیس‌های مختلف با یک کد واحد را برای شما فراهم می‌سازد،بطوریکه اگر بخواهید برنامه ای بنویسید که قابلیت اتصال به Oracle و SqlServer و دیگر دیتابیس‌ها را داشته باشد، استفاده از DbProviderFactory ، کار شما را تسهیل می‌نماید.

DbProviderFactory  در Net Framework 2.0. ارائه شده است.برای درک و چگونگی استفاده از DBProviderFactory مثالی را بررسی می‌نماییم.
ابتدا کد زیر را درون یک فرم کپی نمایید:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.Common;

namespace DBFactory
{
    public partial class Form1 : Form
    {
        private string _MySQLProvider = "MySql.Data.MySqlClient";
        private string _SQLProvider="System.Data.SqlClient";
        private string _OracleProvider ="System.Data.OracleClient";
        private DbProviderFactory _DbProviderFactory;
        private DbConnection _DbConnection = null;
        private DbCommand _DbCommand = null;
        private DbDataAdapter _DbDataAdapter = null;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            try
            {

             string _SQLconnectionstring = "Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=Test;Data Source=FARHAD-PC";
             string _Oracleconnectionstring = "Data Source=ServiceName;User Id=Username;Password=Password";
             
            _DbProviderFactory = DbProviderFactories.GetFactory(_SQLProvider);
            _DbConnection = _DbProviderFactory.CreateConnection();
            _DbConnection.ConnectionString = _SQLconnectionstring;
            
            _DbConnection.Open();

            if (_DbConnection.State == ConnectionState.Closed)
            {

                MessageBox.Show("اتصال با دیتابیس برقرار نشده است");
            }
            else
            {
                MessageBox.Show("اتصال با دیتابیس با موفقیت بر قرار شده است");
            }
            }
            catch (System.Exception excep)
            {
                MessageBox.Show(excep.Message.ToString());    
            }         

        }
    }
}

برای استفاد از DBProviderFactory می‌بایست از فضای نامی System.Data.Common استفاده نمایید. بعد از اعلان کلاس فرم تعدادی آبجکت تعریف شده است، که سه آبجکت ابتدایی آن، بیانگر Provider دیتابیس‌های MySQL،SQLSERVER و Oracle می‌باشد:
 private string _MySQLProvider = "MySql.Data.MySqlClient";
 private string _SQLProvider="System.Data.SqlClient";
 private string _OracleProvider ="System.Data.OracleClient";
Provider‌های بیان شده، جهت استفاده DBFactory برای تشخیص نوع Database می‌باشد، تا بتواند آبجکت‌های مربوط به دیتابیس را ایجاد و در اختیار برنامه نویس قرار دهد. در این مثال ارتباط با دیتابیس SQLSERVER را امتحان می‌کنیم. بنابراین خواهیم داشت:
_DbProviderFactory = DbProviderFactories.GetFactory("System.Data.SqlClient");

در کد بالا، Provider، دیتابیس SQLSERVER به DbProviderFactory به عنوان ورودی داده شده است، بنابراین آبجکتهای مربوط به دیتابیس SQL Server ایجاد و در اختیار شما قرار می‌گیرد.

اگر به نام فضای نامی System.Data.Common توجه نمایید،از کلمه Common استفاده شده است و منظور این است که تمامی کلاسهایی را که این فضای نامی ارائه می‌دهد، در هر دیتابیسی قابل استفاده می‌باشد. برای تشخیص، کلاسهای مربوط به این فضای نامی نیز در ابتدای نام آنها از دو حرف DB استفاده شده است. تمامی کلاسهای زیر در فضای نامی System.Data.Common قابل ارائه و استفاده می‌باشد:
DbCommand 
DbCommandBuilder 
DbConnection 
DbDataAdapter 
DbDataReader 
DbException 
DbParameter 
DbTransaction

جهت اطلاع: ممکن است سئوالی در ذهن شما ایجاد شود که دات نت چگونه براساس نام Provider نوع دیتابیس را تشخیص می‌دهد؟
جواب: زمانی که دیتابیس‌های مختلف روی سیستم شما نصب می‌شود، Provider‌های مربوط به هر دیتابیس درون فایل Machine.config که مربوط به دات نت میباشد، درج می‌شود. و دات نت براساس اطلاعات مربوط به همین فایل آبجکت‌های دیتابیس را ایجاد می‌نماید.

امیدوارم مطلب فوق مفید واقع شود.
نظرات مطالب
افزونه نویسی برای مرورگرها : قسمت دوم : فایرفاکس
در مورد ذخیره سازی لوکال مرورگر که در بالا همان اول مقاله توضیح دادم و در کروم هم که گفتیم با کد زیر اینکارو انجام میدیم:
chrome.storage.local.set
chrome.storage.sync.set
این نکته را هم خاطرنشان کنم که در فایرفاکس ذخیره مقادیر  تا حجم حدودی 5 مگابایت میسر است
در مورد اتصال به دیتابیس sqlite میتونید از این لینک کمک بگیرید که به موارد دیگه هم لینک شده و اگر دقت کنید می‌بینید که میتوانید از کدهای ++c هم استفاده کنید و همینطور اینجا  هم که یک نفر پرسش کرده و یکی هم پاسخش را داده.
در مورد بقیه اتصالات به بانک هایی چون sql server و ... هم میتوانید از طریق api‌ها یا وب سرویس‌ها عمل کنید که نیاز به یک فایل jquery برای اتصال به آن‌ها دارید یا فریمورک‌های جاوااسکریپتی که در این زمینه مهیا شده است.
این مقاله هم ممکنه براتون جالب باشه
مطالب
EF Code First #13

استفاده مستقیم از عبارات SQL در EF Code first

طراحی اکثر ORMهای موجود به نحوی است که برنامه نهایی شما را مستقل از بانک اطلاعاتی کنند و این پروایدر نهایی است که معادل‌های صحیح بسیاری از توابع توکار بانک اطلاعاتی مورد استفاده را در اختیار EF قرار می‌دهد. برای مثال در یک بانک اطلاعاتی تابعی به نام substr تعریف شده، در بانک اطلاعاتی دیگری همین تابع substring نام دارد. اگر برنامه را به کمک کوئری‌های LINQ تهیه کنیم، نهایتا پروایدر نهایی مخصوص بانک اطلاعاتی مورد استفاده است که این معادل‌ها را در اختیار EF قرار می‌دهد و برنامه بدون مشکل کار خواهد کرد. اما یک سری از موارد شاید معادلی در سایر بانک‌های اطلاعاتی نداشته باشند؛ برای مثال رویه‌های ذخیره شده یا توابع تعریف شده توسط کاربر. امکان استفاده از یک چنین توانایی‌هایی نیز با اجرای مستقیم عبارات SQL در EF Code first پیش بینی شده و بدیهی است در این حالت برنامه به یک بانک اطلاعاتی خاص گره خواهد خورد؛ همچنین مزیت استفاده از کوئری‌های Strongly typed تحت نظر کامپایلر را نیز از دست خواهیم داد. به علاوه باید به یک سری مسایل امنیتی نیز دقت داشت که در ادامه بررسی خواهند شد.


کلاس‌های مدل مثال جاری

در مثال جاری قصد داریم نحوه استفاده از رویه‌های ذخیره شده و توابع تعریف شده توسط کاربر مخصوص SQL Server را بررسی کنیم. در اینجا کلاس‌های پزشک و بیماران او، کلاس‌های مدل برنامه را تشکیل می‌دهند:

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; }
}
}

کلاس Context برنامه به نحو زیر تعریف شده:

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; }
}
}

و اینبار کلاس DbMigrationsConfiguration تعریف شده اندکی با مثال‌های قبلی متفاوت است:

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 + '%'");
}
}
}

در اینجا از متد Seed علاوه بر مقدار دهی اولیه جداول، برای تعریف یک رویه ذخیره شده به نام FindDoctorsStartWith و یک تابع سفارشی به نام FindDoctorPatientsCount نیز استفاده شده است. متد context.Database.ExecuteSqlCommand مستقیما یک عبارت SQL را بر روی بانک اطلاعاتی اجرا می‌کند.

در ادامه کدهای کامل برنامه نهایی را ملاحظه می‌کنید:
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);
}
}
}
}
}

توضیحات

همانطور که ملاحظه می‌کنید، برای اجرای مستقیم یک عبارت SQL صرفنظر از اینکه یک رویه ذخیره شده است یا یک تابع و یا یک کوئری معمولی، باید از متد db.Database.SqlQuery استفاده کرد. خروجی این متد از نوع IEnumerable است و این توانایی را دارد که رکوردهای بازگشت داده شده از بانک اطلاعاتی را به خواص یک کلاس به صورت خودکار نگاشت کند.
پارامتر اول متد db.Database.SqlQuery، عبارت SQL مورد نظر است. پارامتر دوم آن باید توسط وهله‌هایی از کلاس SqlParameter مقدار دهی شود. به کمک SqlParameter نام پارامتر مورد استفاده، مقدار و نوع آن مشخص می‌گردد. همچنین Direction آن نیز برای استفاده از رویه‌های ذخیره شده ویژه‌ای که دارای پارامتری از نوع out هستند درنظر گرفته شده است.

چند نکته

- در متد runSp فوق، متد الحاقی ToList را حذف کرده و برنامه را اجرا کنید. بلافاصله پیغام خطای «The SqlParameter is already contained by another SqlParameterCollection.» ظاهر خواهد شد. علت هم این است که با بکارگیری متد ToList، تمام عملیات یکبار انجام شده و نتیجه بازگشت داده می‌شود اما اگر به صورت مستقیم از خروجی IEnumerable آن استفاده کنیم، در حلقه foreach تعریف شده، ممکن است این فراخوانی چندبار انجام شود. به همین جهت ذکر متد ToList در اینجا ضروری است.

- عنوان شد که در اینجا باید به مسایل امنیتی دقت داشت. بدیهی است امکان نوشتن یک چنین کوئری‌هایی نیز وجود دارد:

db.Database.SqlQuery<Doctor>("exec FindDoctorsStartWith "+ txtName.Text, nameParameter).ToList()

در این حالت به ظاهر مشغول به استفاده از رویه‌های ذخیره شده‌ای هستیم که عنوان می‌شود در برابر حملات تزریق SQL در امان هستند، اما چون در کدهای ما به نحو ناصحیحی با جمع زدن رشته‌ها مقدار دهی شده است، برنامه و بانک اطلاعاتی دیگر در امان نخواهند بود. بنابراین در این حالت استفاده از پارامترها را نباید فراموش کرد.
زمانیکه از کوئری‌های LINQ استفاده می‌شود تمام این مسایل توسط EF مدیریت خواهد شد. اما اگر قصد دارید مستقیما عبارات SQL را فراخوانی کنید، تامین امنیت برنامه به عهده خودتان خواهد بود.

- در متد usingSqlFunctions از SqlFunctions.IsNumeric استفاده شده است. این مورد مختص به SQL Server است و امکان استفاده از توابع توکار ویژه SQL Server را در کوئری‌های LINQ برنامه فراهم می‌سازد. برای مثال متدالحاقی از پیش تعریف شده‌ای به نام IsNumeric به صورت مستقیم در دسترس نیست، اما به کمک کلاس SqlFunctions این تابع و بسیاری از توابع دیگر توکار SQL Server قابل استفاده خواهند بود.
اگر علاقمند هستید که لیست این توابع را مشاهده کنید، در ویژوال استودیو بر روی SqlFunctions کلیک راست کرده و گزینه Go to definition را انتخاب کنید.


اشتراک‌ها
5 زبان تابعی برتر برنامه نویسی در سال 2024

Top Functional Programming Languages to Learn in 2024

Functional programming languages encourage a different approach to solving problems, often leading to cleaner and more predictable code. By focusing on pure functions, avoiding side effects, and utilizing higher-order functions, functional programming can improve code quality and reduce bugs. Additionally, these languages are well-suited for concurrent and parallel programming, making them valuable in modern, high-performance computing environments.

5 زبان تابعی برتر برنامه نویسی در سال 2024