همچنین اگر از FTS در SQL Server استفاده میکنید باید از accent insensitive collate استفاده کنید.
حذف اعراب از حروف و کلمات
همچنین اگر از FTS در SQL Server استفاده میکنید باید از accent insensitive collate استفاده کنید.
using FluentNHibernate;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHSample1.Mappings;
namespace ConsoleTestApplication
{
class CDb
{
public static void CreateDb(IPersistenceConfigurer dbType)
{
var cfg = Fluently.Configure().Database(dbType);
PersistenceModel pm = new PersistenceModel();
pm.AddMappingsFromAssembly(typeof(CustomerMapping).Assembly);
var sessionSource = new SessionSource(
cfg.BuildConfiguration().Properties,
pm);
var session = sessionSource.CreateSession();
sessionSource.BuildSchema(session, true);
}
}
}
CDb.CreateDb(
MsSqlConfiguration
.MsSql2008
.ConnectionString("Data Source=(local);Initial Catalog=HelloNHibernate;Integrated Security = true")
.ShowSql());
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHSample1.Mappings;
namespace ConsoleTestApplication
{
class Config
{
public static ISessionFactory CreateSessionFactory(IPersistenceConfigurer dbType)
{
return
Fluently.Configure().Database(dbType
).Mappings(m => m.FluentMappings.AddFromAssembly(typeof(CustomerMapping).Assembly))
.BuildSessionFactory();
}
}
}
using System;
using NHibernate;
using NHSample1.Domain;
namespace ConsoleTestApplication
{
class CDbOperations
{
ISessionFactory _factory;
public CDbOperations(ISessionFactory factory)
{
_factory = factory;
}
public int AddNewCustomer()
{
using (ISession session = _factory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
Customer vahid = new Customer()
{
FirstName = "Vahid",
LastName = "Nasiri",
AddressLine1 = "Addr1",
AddressLine2 = "Addr2",
PostalCode = "1234",
City = "Tehran",
CountryCode = "IR"
};
Console.WriteLine("Saving a customer...");
session.Save(vahid);
session.Flush();//چندین عملیات با هم و بعد
transaction.Commit();
return vahid.Id;
}
}
}
public void DeleteCustomer(int id)
{
using (ISession session = _factory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
Customer customer = session.Load<Customer>(id);
Console.WriteLine("Id:{0}, Name: {1}", customer.Id, customer.FirstName);
Console.WriteLine("Deleting a customer...");
session.Delete(customer);
session.Flush();//چندین عملیات با هم و بعد
transaction.Commit();
}
}
}
}
}
using System;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHSample1.Domain;
namespace ConsoleTestApplication
{
class Program
{
static void Main(string[] args)
{
//CDb.CreateDb(SQLiteConfiguration.Standard.ConnectionString("data source=sample.sqlite").ShowSql());
//return;
//todo: Read ConnectionString from app.config or web.config
using (ISessionFactory session = Config.CreateSessionFactory(
MsSqlConfiguration
.MsSql2008
.ConnectionString("Data Source=(local);Initial Catalog=HelloNHibernate;Integrated Security = true")
.ShowSql()
))
{
CDbOperations db = new CDbOperations(session);
int id = db.AddNewCustomer();
Console.WriteLine("Loading a customer and delete it...");
db.DeleteCustomer(id);
}
Console.WriteLine("Press a key...");
Console.ReadKey();
}
}
}
Saving a customer...
NHibernate: select next_hi from hibernate_unique_key with (updlock, rowlock)
NHibernate: update hibernate_unique_key set next_hi = @p0 where next_hi = @p1;@p0 = 17, @p1 = 16
NHibernate: INSERT INTO [Customer] (FirstName, LastName, AddressLine1, AddressLine2, PostalCode, City, CountryCode, Id) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7);@p0 = 'Vahid', @p1 = 'Nasiri', @p2 = 'Addr1', @p3 = 'Addr2', @p4 = '1234', @p5 = 'Tehran', @p6 = 'IR', @p7 = 16016
Loading a customer and delete it...
NHibernate: SELECT customer0_.Id as Id2_0_, customer0_.FirstName as FirstName2_0_, customer0_.LastName as LastName2_0_, customer0_.AddressLine1 as AddressL4_2_0_, customer0_.AddressLine2 as AddressL5_2_0_, customer0_.PostalCode as PostalCode2_0_, customer0_.City as City2_0_, customer0_.CountryCode as CountryC8_2_0_ FROM [Customer] customer0_ WHERE customer0_.Id=@p0;@p0 = 16016
Id:16016, Name: Vahid
Deleting a customer...
NHibernate: DELETE FROM [Customer] WHERE Id = @p0;@p0 = 16016
Press a key...
CDb.CreateDb(SQLiteConfiguration.Standard.ConnectionString("data source=sample.sqlite").ShowSql());
//todo: Read ConnectionString from app.config or web.config
using (ISessionFactory session = Config.CreateSessionFactory(
SQLiteConfiguration.Standard.ConnectionString("data source=sample.sqlite").ShowSql()
))
{
...
let names = ["Jack", "Jecci", "Ram", "Tom"]; let upperCaseNames = []; for(let i=0, totalNames = names.length; i< totalNames ; i= i +1) { upperCaseNames = names[i].toUpperCase(); }
let names = ["Jack", "Jecci", "Ram", "Tom"]; let upperCaseNames = names.map(name => name.toUpperCase());
function print(name) { console.log(name); } let names = ["Jack", "Jecci", "Ram", "Tom"]; for(let i=0, totalNames = names.length; i< totalNames ; i= i +1) { print(names[i]) }
function print(name) { console.log(name); } let names = ["Jack", "Jecci", "Ram", "Tom"]; names.forEach(name=> print(name)); // اگر صرفا چاپ در کنسول مد نظر هست let names = ["Jack", "Jecci", "Ram", "Tom"]; names.forEach(name=> console.log(name));
function isOdd(n) { return n %2; } let numbers = [1,2,3,4,5]; let odd = []; for(let i=0, total = numbers.length; i< total ; i= i +1) { let number = numbers[i]; if( isOdd(number) ) { odd.push(number); } }
let numbers = [1,2,3,4,5, 6, 7] let odd = numbers.filter(n => n%2);
let numbers = [1,2,3,4,5] let result = 0; for(let i=0, total = numbers.length; i< total ; i= i +1) { result = result + numbers[i]; }
let numbers = [1,2,3,4,5,6,7]; function sum(accumulator, currentValue){ return accumulator + currentValue; } let initialVal = 0; let result = numbers.reduce(sum, initialVal); // یا بصورت زیر کد را خلاصه نمود let numbers = [1,2,3,4,5,6,7, 10]; let result = numbers.reduce((acc, val)=> acc+val, 0);
let names = ["ram",, "rahul", "raj", "rahul"]; for(let i=0, totalNames = names.length; i< totalNames ; i= i +1) { if(names[i] === "rahul") { console.log(" found rahul"); break; } }
let names = ["ram",, "rahul", "raj", "rahul"]; let isRahulPresent = names.some(name => name==="rahul"); if(isRahulPresent) { console.log("found rahul"); }
let numbers = [1,2,3,4,5, 0]; for(let i=0, total = numbers.length; i< total ; i= i +1) { if(numbers[i] <= 0) { console.log("0 present in array"); break; } }
let numbers = [1,2,3,4,5,0]; let isZeroFree = numbers.every(e => e > 0); if(!isZeroFree) { console.log("0 present in array"); }
//It's only for code review purpose!
using System.Data;
using System.Data.SqlClient;
using System.Web.Configuration;
public sealed class SqlHelper
{
private SqlHelper() { }
// Send Connection String
//---------------------------------------------------------------------------------------
public static string GetCntString()
{
return WebConfigurationManager.ConnectionStrings["db_ConnectionString"].ConnectionString;
}
// Connect to Data Base SqlServer
//---------------------------------------------------------------------------------------
public static SqlConnection Connect2Db(ref SqlConnection sqlCnt, string cntString)
{
try
{
if (sqlCnt == null) sqlCnt = new SqlConnection();
sqlCnt.ConnectionString = cntString;
if (sqlCnt.State != ConnectionState.Open) sqlCnt.Open();
return sqlCnt;
}
catch (SqlException)
{
return null;
}
}
// Run ExecuteScalar Command
//---------------------------------------------------------------------------------------
public static string RunExecuteScalarCmd(ref SqlConnection sqlCnt, string strCmd, bool blnClose)
{
Connect2Db(ref sqlCnt, GetCntString());
using (sqlCnt)
{
using(SqlCommand sqlCmd = sqlCnt.CreateCommand())
{
sqlCmd.CommandText = strCmd;
object objResult = sqlCmd.ExecuteScalar();
if (blnClose) CloseCnt(ref sqlCnt, true);
return (objResult == null) ? string.Empty : objResult.ToString();
}
}
}
// Close SqlServer Connection
//---------------------------------------------------------------------------------------
public static bool CloseCnt(ref SqlConnection sqlCnt, bool nullSqlCnt)
{
try
{
if (sqlCnt == null) return true;
if (sqlCnt.State == ConnectionState.Open)
{
sqlCnt.Close();
sqlCnt.Dispose();
}
if (nullSqlCnt) sqlCnt = null;
return true;
}
catch (SqlException)
{
return false;
}
}
}
protected void BtnTest_Click(object sender, EventArgs e)
{
SqlConnection sqlCnt = new SqlConnection();
string strQuery = "SELECT COUNT(UnitPrice) AS PriceCount FROM [Order Details]";
// در این مرحله پارامتر سوم یعنی کانکشن باز نگه داشته شود
string strResult = SqlHelper.RunExecuteScalarCmd(ref sqlCnt, strQuery, false);
strQuery = "SELECT LastName + N'-' + FirstName AS FullName FROM Employees WHERE (EmployeeID = 9)";
// در این مرحله پارامتر سوم یعنی کانکشن بسته شود
strResult = SqlHelper.RunExecuteScalarCmd(ref sqlCnt, strQuery, true);
}
/// <summary>
///
/// </summary>
/// <param name="sqlCnt"></param>
/// <param name="cntString"></param>
/// <returns></returns>
public static SqlConnection Connect2Db(ref SqlConnection sqlCnt, string cntString)
در بسیاری موارد (مانند سیستمهای Multi Tenant) لازم هست تا مانع از این شویم که دادههای کاربران با هم تداخل پیدا کند و یا آنها بتوانند به دادههای هم دسترسی داشته باشند. مثلا میخواهیم کاربران هر شعبه از سازمان، تنها به اطلاعات شعبه خودشان دسترسی داشته باشند. یک کار ساده، پردردسر و بسیار بد آن است که از برنامه نویسها بخواهیم در هر کوئری عبارتی را اضافه کنند که سطح دسترسی را چک کند. اما اگر برنامه نویس جایی فراموش کرد چی؟ اگر سیاست دسترسی پیچیدهتر بود و مبنی بر پارامترهای مختلف محاسبه میشد چه خواهد شد؟ این راهکار در حجم بزرگ غیر مطمئن و غیرقابل نگهداری است.
در EF6 قابلیتی به نام Interception وجود دارد که با استفاده از آن میتوان سیاست دسترسی به داده را در لایههای پایینی طراحی کرد. در این روش برنامه نویس لایه هایی بالا، بدون آنکه درگیر مفاهیمی مانند Tenant و سیاستها بشود، میتواند به راحتی کوئری هایش را تولید کند. سپس EF به طور خودکار تغییری در کوئریها خواهد داد تا دسترسیهای لازم رعایت کرده باشد. برای اینکار میتوانید از کتابخانه EntityFramework.DynamicFilters استفاده کنید.
این روش هم علی رغم همه مزایا معایبی هم دارد. اگر بخواهیم از همین پایگاه داده استفاده کنیم ولی در محیط دات نت نباشیم و یا از EF6 استفاده نکنیم، دوباره مشکلات اغاز میشوند. سیاستها را باید در همه جا کپی کنیم و در صورت لزوم هم، مجددا همه را تغییر دهیم.
در SQL Server 2016 قابلیتی به نام Row Level Security وجود دارد، که به ما اجازه میدهد سیاستهای دسترسی با داده را در لایه پایگاه داده متمرکز کنیم. در این صورت اپلیکشنها هیچگونه آگاهی ایی نسبت به سیاستها نخواهند داشت و درگیر این مفاهیم در سطح کد نخواهیم بود. همچنین در صورت لزوم به تغییر سیاست ها، فقط لازم است تغییراتی را در پایگاه داده بدهیم. با این روش، به هر طریقی و از هر ابزاری که به پایگاه داده کوئری هایمان را ارسال کنیم، سیاستهای دسترسی به داده اعمال خواهند شد و امنیت بالا و البته ریزدانه ای (granular) را خواهیم داشت.
در مثال زیر خواهیم دید که چگونه میتوان با استفاده از EF6 از ویژگی RLS بهره برد. این مثال یکی دیگر از کاربردهای Interception را نیز توضیح میدهد.
public class Bill { public int Id { set; get; } public string Name { set; get; } public virtual ICollection<Transaction> Transactions { set; get; } } public class Transaction { public int Id { set; get; } public DateTime AddDate { set; get; } public int Amount { set; get; } [ForeignKey("BillId")] public virtual Bill Bill { set; get; } public int BillId { set; get; } }
public class MyContext : DbContext { public DbSet<Bill> Bills { get; set; } public DbSet<Transaction> Transactions { get; set; } }
public class Configuration : DbMigrationsConfiguration<MyContext> { public Configuration() { AutomaticMigrationsEnabled = true; AutomaticMigrationDataLossAllowed = true; } protected override void Seed(MyContext context) { var bill1 = new Bill { Name = "bill-1" }; context.Bills.Add(bill1); for (int i = 0; i < 11; i++) { context.Transactions.Add(new Transaction { AddDate = DateTime.Now.AddDays(-i), Amount = 1000000000 + i, Bill = bill1 }); } base.Seed(context); } }
public static class Test { public static void RunTests() { Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Configuration>()); using (var context = new MyContext()) { var sum = context.Transactions.Sum(x => x.Amount); Console.WriteLine(sum); } } }
SELECT [GroupBy1].[A1] AS [C1] FROM ( SELECT SUM([Extent1].[Amount]) AS [A1] FROM [dbo].[Transactions] AS [Extent1] ) AS [GroupBy1]
Arithmetic overflow error converting expression to data type int.
var sum2 = context.Transactions.Sum(x => (Int64)x.Amount);
SELECT [GroupBy1].[A1] AS [C1] FROM ( SELECT SUM( CAST( [Extent1].[Amount] AS bigint)) AS [A1] FROM [dbo].[Transactions] AS [Extent1] ) AS [GroupBy1]
var date = DateTime.Now.AddDays(10); var sum3 = context.Transactions .Where(x => x.AddDate > date) .Sum(x => (Int64)x.Amount);
SELECT [GroupBy1].[A1] AS [C1] FROM ( SELECT SUM( CAST( [Extent1].[Amount] AS bigint)) AS [A1] FROM [dbo].[Transactions] AS [Extent1] WHERE [Extent1].[AddDate] > @p__linq__0 ) AS [GroupBy1]
The cast to value type 'Int64' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type.
var date = DateTime.Now.AddDays(10); var sum3 = context.Transactions .Where(x => x.AddDate > date) .Sum(x => (Int64?)x.Amount) ?? 0;
var sum4 = context.Bills.First().Transactions.Sum(x => (Int64?)x.Amount) ?? 0;
SELECT [Extent1].[Id] AS [Id], [Extent1].[AddDate] AS [AddDate], [Extent1].[Amount] AS [Amount], [Extent1].[BillId] AS [BillId] FROM [dbo].[Transactions] AS [Extent1] WHERE [Extent1].[BillId] = @EntityKeyValue1
var entry = context.Bills.First(); var sum5 = context.Entry(entry).Collection(x => x.Transactions).Query().Sum(x => (Int64?)x.Amount) ?? 0;
SELECT [GroupBy1].[A1] AS [C1] FROM ( SELECT SUM( CAST( [Extent1].[Amount] AS bigint)) AS [A1] FROM [dbo].[Transactions] AS [Extent1] WHERE [Extent1].[BillId] = @EntityKeyValue1 ) AS [GroupBy1]
public class User { public int Id { get; set; } public string Name { get; set; } public virtual ICollection<BlogPost> BlogPosts { get; set; } } public class BlogPost { public int Id { get; set; } public string Title { get; set; } public string Content { get; set; } [ForeignKey("UserId")] public virtual User User { get; set; } public int UserId { get; set; } }
var data = context.BlogPosts.ToList();
var data = context.BlogPosts.ToList();
var list = context.BlogPosts.Select(x => x.Content).Skip(15).Take(15).ToList();
foreach (var post in context.BlogPosts) { Console.WriteLine(post.User.Name); }
foreach (var post in context.BlogPosts.Include(x=>x.User))
var data = context.BlogPosts.ToList();
var data = context.BlogPosts.AsNoTracking().Skip(15).Take(15).ToList();
private void problem5MoreThan1ConnectionPerRequest() { using (var context = new MyContext()) { var count = context.BlogPosts.ToList(); } }
DataContext = from user in context.Users where user.Id>10 select user;
var list = context.BlogPosts.Where(x => x.Content.Contains("test"))
SELECT * FROM table ORDER BY NEWID()
using System; using System.Data.Entity; using System.Data.Entity.Migrations; using System.Linq; namespace Sample { public class User { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } } public class MyContext : DbContext { public DbSet<User> Users { get; set; } } public class Configuration : DbMigrationsConfiguration<MyContext> { public Configuration() { AutomaticMigrationsEnabled = true; AutomaticMigrationDataLossAllowed = true; } protected override void Seed(MyContext context) { context.Users.Add(new User { Name = "User 1", Age = 20 }); context.Users.Add(new User { Name = "User 2", Age = 25 }); context.Users.Add(new User { Name = "User 3", Age = 30 }); context.Users.Add(new User { Name = "User 4", Age = 35 }); context.Users.Add(new User { Name = "User 5", Age = 40 }); base.Seed(context); } } public static class Test { public static void RunTests() { Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyContext, Configuration>()); using (var context = new MyContext()) { var randomListOfUsers = context.Users .Where(person => person.Age >= 25 && person.Age < 40) .OrderBy(person => Guid.NewGuid()) .ToList(); foreach (var person in randomListOfUsers) Console.WriteLine("{0}:{1}", person.Name, person.Age); } } } }
.OrderBy(person => Guid.NewGuid())
ORDER BY NEWID()
SELECT [Project1].[Id] AS [Id], [Project1].[Name] AS [Name], [Project1].[Age] AS [Age] FROM ( SELECT NEWID() AS [C1], ------ Guid created here [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name], [Extent1].[Age] AS [Age] FROM [dbo].[Users] AS [Extent1] WHERE ([Extent1].[Age] >= 25) AND ([Extent1].[Age] < 40) ) AS [Project1] ORDER BY [Project1].[C1] ASC ------ Used for sorting here