Занятие №3 на курса по информационни технологии (2013) провеждан от ДАВИД академия в ПМГ "Никола Обрешков" - Казанлък. Включва темите:
- ADO.NET
- LINQ to SQL
3. ADO.NET
• Какво е „ADO.NET“?
–
–
–
–
Част от .NET Framework
Наследник на ActiveX Data Objects (ADO)
Предоставя удобни начини за достъп до бази данни
Минимална зависимост от избора на СУБД
4. ADO.NET
• ADO.NET доставчици (data providers)
–
–
–
–
–
Data Provider for SQL Server
Data Provider for OLE DB
Data Provider for ODBC
Data Provider for Oracle
Data Provider for SQL Server Compact 4.0
5. ADO.NET
• Модели за достъп до данните в ADO.NET
–
–
–
–
Свързан модел
Несвързан модел
LINQ to SQL
Entity Framework
6. ADO.NET
• Низове за връзка (connection strings)
– Служат за осъществяване на връзката с базата данни
– Представляват поредица от двойки
„параметър=стойност“, разделени с ;
– Различните доставчици поддържат различни
параметри
Server=(local); Database=HealthyFood; Integrated
Security=SSPI
Server=(local); Database=HealthyFood; Integrated
Security=False; User ID=sa; Password=$secret$; Persist
Security Info=False
7. ADO.NET
• Основни параметри на низовете за връзка
–
–
–
–
–
–
Server
Database
Integrated Security
User ID
Password
Persist Security Info
8. ADO.NET
• Автоматично генериране на низове за връзка
– Използва се класът SqlConnectionStringBuilder
– Параметрите на връзката са свойства на обекта
9. ADO.NET
• Съхраняване на низове за връзка в
конфигурационен файл
– Позволява промяна без прекомпилиране на
приложението
– Записва се в секцията <connectionStrings>
– Достъпва се през статичното свойство
ConfigurationManager.ConnectionStrings
10. ADO.NET
• Съхраняване на низове за връзка в
конфигурационен файл
<configuration>
<connectionStrings>
<add name="connection"
providerName="System.Data.SqlClient"
connectionString="Server=(local); Database=HealthyFood; Integrated
Security=SSPI" />
</connectionStrings>
</configuration>
connection.ConnectionString = ConfigurationManager
.ConnectionStrings["connection"].ConnectionString;
11. ADO.NET
• Класът SqlConnection
–
–
–
–
Осъществява връзката с базата данни
Получава connection string
Методът Open()
Имплементира IDisposable
using (var connection = new SqlConnection())
{
connection.ConnectionString = ConfigurationManager
.ConnectionStrings["connection"].ConnectionString;
connection.Open();
// операции върху базата...
}
12. ADO.NET
• Класът SqlCommand
– Служи за изпълнение на заявки
– Получава отворен SqlConnection
– Методите
ExecuteNonQuery(), ExecuteScalar(), ExecuteReade
r()
– Имплементира IDisposable
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "SELECT COUNT(*) FROM [Producers]";
int producerCount = (int)command.ExecuteScalar();
Console.WriteLine("Producers count: {0}", producerCount);
}
13. ADO.NET
• Класът SqlCommand – методът ExecuteReader()
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText = "SELECT [ProducerID], [Name] FROM [Producers]";
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine("ProducerID: {0}; Name: {1}",
reader["ProducerID"], reader["Name"]);
}
}
}
14. ADO.NET
• Класът SqlCommand – параметри
– Служат за динамично предаване на стойности
– Име, тип и стойност
– Свойството Parameters
15. ADO.NET
• Класът SqlCommand – параметри
Console.Write("Input producer ID: ");
int producerID = Convert.ToInt32(Console.ReadLine());
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText =
@"SELECT [BrandID], [Name] FROM [Brands]
WHERE ([ProducerID] = @producer_id)";
command.Parameters.AddWithValue("@producer_id", producerID);
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine("BrandID: {0}; Name: {1}",
reader["BrandID"], reader["Name"]);
}
}
}
16. ADO.NET
• Класът SqlCommand – съхранени процедури
– На свойството CommandType се прсивоява стойност
CommandType.StoredProcedure
– Стойности на параметрите се подават през свойството
Parameters
18. ADO.NET
• Трансакции в ADO.NET – класът
TransactionScope
– Методът Complete()
– Имплементира IDisposable
using (var ts = new TransactionScope())
using (var connection = new SqlConnection())
{
connection.ConnectionString = ConfigurationManager
.ConnectionStrings["connection"].ConnectionString;
connection.Open();
// операции в трансакция
ts.Complete();
}
19. SQL Injection атаки
• Какво е „SQL Injection“?
– Пробив в сигурността на базата данни
– Възможно е да се използва, ако динамично се
генерират заявки с конкатениране на низове
20. SQL Injection атаки
• Пример за SQL Injection
Console.WriteLine("Input brand name to search for: ");
string name = Console.ReadLine();
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText =
@"SELECT [BrandID], [Name] FROM [Brands]
WHERE ([Name] = N'" + name + "')";
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine("BrandID: {0}; Name: {1}",
reader["BrandID"], reader["Name"]);
}
}
}
21. SQL Injection атаки
• Пример за SQL Injection
'); DELETE FROM [Products];--
SELECT [ProductID], [Name] FROM [Products]
WHERE ([Name] = N''); DELETE FROM [Products];--')
22. SQL Injection атаки
• Пример за SQL Injection
Console.WriteLine("Input brand name to search for: ");
string name = Console.ReadLine();
using (SqlCommand command = connection.CreateCommand())
{
command.CommandText =
@"SELECT [BrandID], [Name] FROM [Brands]
WHERE ([Name] = @name)";
command.Parameters.AddWithValue("@name", name);
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
Console.WriteLine("BrandID: {0}; Name: {1}",
reader["BrandID"], reader["Name"]);
}
}
}
23. LINQ
• Разширителни методи на IEnumerable<T>
– Въведени в .NET Framework 3.5
– Улесняват прилагането на често използвани операции
върху колекции
– Следват функционалната парадигма
– Описани в статичния клас System.Linq.Enumerable
24. LINQ
• Разширителни методи на IEnumerable<T>
IEnumerable<U> Select<T, U>(this IEnumerable<T> source, Func<T, U> selector)
IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate)
U Aggregate<T, U>(this IEnumerable<T> source, U seed, Func<U, T, U> function)
IEnumerable<T> Skip<T>(this IEnumerable<T> source, int count)
IEnumerable<T> Take<T>(this IEnumerable<T> source, int count)
25. LINQ
• Разширителни методи на IEnumerable<T> –
отложено изпълнение
var numbers = new List<int>() { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
IEnumerable<int> newNumbers = numbers
.Where(x => x % 2 == 0)
.Select(x => x*2);
// в този момент newNumbers съхранява информация за операциите,
// които трябва да се извършат
numbers.Add(10);
// точно преди началото на обхождането на newNumbers с foreach,
// операциите се изпълняват и резултатът се подава на цикъла
foreach (int n in newNumbers)
{
Console.WriteLine(n);
}
26. LINQ
• Разширителни методи на IEnumerable<T> –
методи, които предизвикват изпълнение
– First, Last, FirstOrDefault, LastOrDefault
– Sum, Min, Max, Average, Count
– ToList, ToArray, ToDictionary
28. LINQ
• Разширителни методи на IEnumerable<T> –
групиране
IEnumerable<IGrouping<U, T>> GroupBy<T, U>(this IEnumerable<T> source,
Func<T, U> keySelector)
29. LINQ
• Разширителни методи на IEnumerable<T> –
съединения
IEnumerable<W> Join<T, U, V, W>(this IEnumerable<T> first,
IEnumerable<U> second,
Func<T, V> firstKeySelector,
Func<U, V> secondKeySelector,
Func<T, U, W> resultSelector)
IEnumerable<W> GroupJoin<T, U, V, W>(
this IEnumerable<T> first,
IEnumerable<U> second,
Func<T, V> firstKeySelector,
Func<U, V> secondKeySelector,
Func<T, IEnumerable<U>, W> resultSelector)
30. LINQ
• Какво е „LINQ“?
– Language INtegrated Query
– Специален синтаксис в C# и Visual Basic .NET, който е
подобен на SQL
– Също въведен в .NET Framework 3.5
– Трансформира се в извиквания на разширителните
методи на IEnumerable<T> и IQueryable<T>
– Няколко различни имплементации
31. LINQ
• LINQ – примери
var example1 = from n in numbers
select n*2;
var example1 = numbers.Select(n => n*2);
32. LINQ
• LINQ – примери
var example2 = from n in numbers
where n > 15
orderby n % 4, n % 7 descending
select n;
var example2 = numbers
.Where(n => n > 15)
.OrderBy(n => n % 4)
.ThenByDescending(n => n % 7);
33. LINQ
• LINQ – примери
var example3 = from n in numbers
group n by n % 3 into ng
where ng.Count() == 2
select ng;
var example3 = numbers
.GroupBy(n => n % 3)
.Where(ng => ng.Count() == 2);
34. LINQ
• LINQ – примери
var example4 = from n in numbers
join m in numbers on n % 3 equals m % 3
select Tuple.Create(n, m);
var example4 = numbers
.Join(numbers, n => n % 3, m => m % 3, (n, m) => Tuple.Create(n, m));
35. LINQ
• Интерфейсът IQueryable<T>
– Наследява IEnumerable<T>
– Различна имплементация на повечето разширителни
методи на IEnumerable<T>
– Служи за трансформиране на LINQ заявки към
SQL, XPath и др.
– Клас с разширителни методи System.Linq.Queryable
36. LINQ
• Имплементации на LINQ
–
–
–
–
–
LINQ to Objects
LINQ to XML
LINQ to Dataset
LINQ to SQL
LINQ to Entities
37. LINQ to SQL
• Какво е „LINQ to SQL“?
– Част от ADO.NET
– Въведен в .NET Framework 3.5
– Object-Relational Mapping (ORM) – ръчно дефиниране
или описване с DBML
– Само с Data Provider for SQL Server
– Пространството от имена System.Data.Linq
38. LINQ to SQL
• Ръчно описване на ORM модела
– Прави се с атрибути
– Пространството от имена System.Data.Linq.Mapping
39. LINQ to SQL
• Ръчно описване на ORM модела – таблици
– Атрибутът Table
– Атрибутът Column
[Table(Name = "Producers")]
public class Producer
{
[Column(IsPrimaryKey = true)]
public int ProducerID { get; set; }
[Column(CanBeNull = false)]
public string Name { get; set; }
[Column]
public string Country { get; set; }
}
40. LINQ to SQL
• Ръчно описване на ORM модела – връзки
– Атрибутът Association
– Типовете EntitySet<T> и EntityRef<T>
41. LINQ to SQL
• Ръчно описване на ORM модела – връзки
[Table(Name = "Producers")]
public class Producer
{
private EntitySet<Brand> _brands;
[Column(IsPrimaryKey = true)]
public int ProducerID { get; set; }
[Column(CanBeNull = false)]
public string Name { get; set; }
[Column]
public string Country { get; set; }
[Association(Storage = "_brands", OtherKey = "ProducerID")]
public EntitySet<Brand> Brands
{
get { return _brands; }
set { _brands.Assign(value); }
}
}
42. LINQ to SQL
• Ръчно описване на ORM модела – връзки
[Table(Name = "Brands")]
public class Brand
{
private EntityRef<Producer> _producer;
[Column(IsPrimaryKey = true)]
public int BrandID { get; set; }
[Column]
public int ProducerID { get; set; }
[Column(CanBeNull = false)]
public string Name { get; set; }
[Column]
public string Description { get; set; }
[Association(Storage = "_producer", ThisKey = "ProducerID")]
public Producer Producer
{
get { return _producer.Entity; }
set { _producer.Entity = value; }
}
}
43. LINQ to SQL
• Ръчно описване на ORM модела – контекст
– Базовият клас DataContext
public class HealthyFoodContext : DataContext
{
public HealthyFoodContext(string connectionString)
: base(connectionString) { }
public Table<Producer> Producers
{
get { return GetTable<Producer>(); }
}
public Table<Brand> Brands
{
get { return GetTable<Brand>(); }
}
}
string connectionString =
ConfigurationManager.ConnectionStrings["connection"].ConnectionString;
var context = new HealthyFoodContext(connectionString);
44. LINQ to SQL
• Примерни заявки
IEnumerable<Brand> brands = from b in context.Brands
select b;
IEnumerable<Brand> brands = from b in context.Brands
where b.BrandID > 3
select b;
var brands = from b in context.Brands
select new { BrandID = b.BrandID, BrandName = b.Name };
var brands = from b in context.Brands
select new { ProducerName = b.Producer.Name,
BrandName = b.Name };
IEnumerable<Brand> brands = context.Producers
.Where(p => p.Name != "Kraft Foods")
.SelectMany(p => p.Brands);
Producer producer = context.Producers.Single(p => p.ProducerID == 3);
45. LINQ to SQL
• Описване на ORM модела с DBML
–
–
–
–
Специализиран XML документ
LINQ to SQL Classes файлов шаблон
Автоматично генериране на C# код
partial класове - добавяне на методи/свойства във
външни файлове