1. Trang chủ
  2. » Tất cả

Chapter 6 - LINQ to SQL

46 420 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề LINQ to SQL
Trường học SELA Software & Education Labs Ltd.
Thể loại Chương
Thành phố Bnei Brak
Định dạng
Số trang 46
Dung lượng 479,78 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Bnei Brak 51202 IsraelIQueryable • LINQ to SQL isn’t based on IEnumerable • Instead, Table implements IQueryable – Contains an Expression Tree • This expression tree is parsed by the qu

Trang 1

LINQ via C# 3.0

Chapter 6 – LINQ to SQL

Trang 2

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

LINQ to Relational Data

Trang 3

LINQ to DataSet

• DataSets and DataTables do not

implement IEnumerable

– You could roll your own

• LINQ provides an AsEnumerable()

extension for DataSets in

System.Data.DataSetExtensions.dll

Trang 4

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

from book in books

select book Field<string> ("author");

Array.ForEach(authors.ToArray(),

Console.WriteLine);

• LINQ to DataSet can be used as an

object-based LINQ to XML!

Trang 5

LINQ to SQL

• The primary challenge:

– Abstracting away the data source

• DataSets are filled and queried in a

non-standard way

• But LINQ to Objects != DB access

– Retrieve 15 rows from a 1,000,000-row table

– Retrieve items based on DB indexes

– Support DB-paging, partitioning, views, sprocs,

Trang 6

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

IQueryable

• LINQ to SQL isn’t based on IEnumerable

• Instead, Table<T> implements

IQueryable

– Contains an Expression Tree

• This expression tree is parsed by the query provider at runtime

Trang 7

Data Source Abstraction

• We still use the same LINQ keywords and query operators

– The query provider translates them into something

else and executes them

– SQL, Web Service calls, REST URLs,

from student in students

WHERE [t1].[StudentId] = [t0].[Id]

) AS [Average]

FROM [dbo].[Students] AS [t0]

LINQ to SQL Provider

students is IQueryable<Studen

t>

Trang 8

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

Mapping Data to Objects

• LINQ to Objects:

– Data = objects

• LINQ to SQL:

– Data = normalized relational database tables

– Objects = business entities, DAL, data contracts,

• System.Data.Linq.Mapping MappingSour ce

– AttributeMappingSource

– XmlMappingSource

LINQ to SQL is an Object-Relational

Mapper

Trang 9

Attribute-Based Mapping

[ Table (Name=“Courses”)]

public class Course

{

[ Column ( IsPrimaryKey =true]

public int Id {get;set;}

Trang 10

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

The Data Context

• The DataContext class is the LINQ to

SQL orchestrator

using ( DataContext context =

new DataContext (@"D:\Temp\

CourseManagement.mdf")) {

context Log = Console.Out;

var product =

from student in context GetTable<Student> ()

from course in context GetTable<Course> ()

select new { Student=student, Course=course };

Table<Grade> grades = context GetTable<Grade> ();

int lastGradeId =

(from grade in grades

select (int?)grade.Id).Max() ?? 0;

Connection string, mapping source

Obtain data source

Table<T> is IQueryable

Trang 11

DataContext Notes

• DataContext is not just a portal to the

entities

• It tracks changes and detects conflicts

• It guarantees object identity

• It is decoupled from the mapping source

• It is lightweight: One per method scope

Trang 12

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

What’s Supported

?

• All language-integrated query operators

• Most standard query operators

• Inserts, updates and deletes

• Custom SQL commands (strings)

• Database creation from mapping

• Transactional work

• Preloading data (local queries)

• Optimistic locking (concurrency control)

Trang 14

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

Inserting Data

using (DataContext context ) {

Student alex = new Student { Id = 49, Name = "Alex" };

context.GetTable<Student>() InsertOnSubmit (alex);

//New student gets an automatic 100 in first two courses int lastGradeId = context.GetTable<Grade>().Max(g =>

Trang 15

Deleting Data

using (DataContext context ) {

foreach (Student student in

context.GetTable<Student>() Where (

s => s.Grades Average (g => g.Value) < 80)) {

//Manual cascading delete

foreach (Grade grade in

Trang 16

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

Conflict Management

• Optimistic locking allows for conflict control when examining and submitting changes

using (CourseManagementDataContext context ) {

ChangeSet changeSet = context GetChangeSet ();

foreach (var conflict in context ChangeConflicts ) { conflict Resolve ( RefreshMode.KeepCurrentValues );

foreach (var memberConflict in

Expensive: Checks all members

Use a timestamp or a version field

[Column(IsVersion=true, …)]

Or avoid altogether

[Column(UpdateCheck=UpdateCheck.Never,

…)]

Trang 18

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

Explicit Transaction

• Transactions can be performed explicitly

– Not recommended if distributed transactions are

Trang 19

Database Creation from Mapping

• With an initialized context, we can create

the database from the mapping

– Objects-first, schema-later!

– (Schema-first to be discussed shortly)

using (DataContext context =

Table<Grade> grades = context.GetTable<Grade>();

Table<Course> courses = context.GetTable<Course>();

if (context DatabaseExists ())

context DeleteDatabase ();

DROP DATABASE [D:\Temp\CourseManagement.mdf]

CREATE DATABASE [D:\Temp\CourseManagement.mdf] ON PRIMARY (NAME='CourseManagement.mdf', FILENAME='D:\Temp\CourseManagement.mdf') LOG ON

(NAME='CourseManagement.ldf', FILENAME='D:\Temp\CourseManagement.ldf')

SET ARITHABORT ONCREATE TABLE [dbo].[Students](

[Id] Int NOT NULL, [Name] NVarChar(MAX) NOT NULL, CONSTRAINT [PK_dbo.Students] PRIMARY KEY ([Id]) )

CREATE TABLE [dbo].[Grades](

[Id] Int NOT NULL, [StudentId] Int NOT NULL, [CourseId] Int NOT NULL, [Value] Int NOT NULL, CONSTRAINT [PK_dbo.Grades] PRIMARY KEY ([Id]) )

CREATE TABLE [dbo].[Courses](

[Id] Int NOT NULL, [Name] NVarChar(MAX) NOT NULL, CONSTRAINT [PK_dbo.Courses] PRIMARY KEY ([Id]) )

ALTER TABLE [dbo].[Grades]

ADD CONSTRAINT [Course_Grade] FOREIGN KEY ([CourseId]) REFERENCES [dbo].[Courses]([Id])ALTER TABLE [dbo].[Grades]

ADD CONSTRAINT [Student_Grade] FOREIGN KEY ([StudentId]) REFERENCES [dbo].[Students]([Id])

Trang 20

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

Custom SQL Commands

• Custom SQL commands are fully

supported: can return mapped entities!

using (DataContext context ) {

var students = context ExecuteQuery<Student> (

"SELECT TOP(2) Id FROM Students WHERE Id > @p0“, 2);

foreach (Student student in students) {

>

Trang 21

Stored Procedures

• Stored procedures can be executed as

custom SQL commands:

using (DataContext context ) {

foreach (Student failedStudent in

@FailingGrade int = 70 )

AS SELECT * FROM Students WHERE

(SELECT AVG(Value) FROM Grades

WHERE Grades.StudentId = Students.Id) < @FailingGrade;

Trang 22

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

Stored Procedures

• Stored procedures can be mapped to

methods using [Function]

class FailedStudentDataContext : DataContext {

[ Function (Name = "GetFailingStudents")]

public ISingleResult<Student> GetFailingStudents( [ Parameter (Name = "FailingGrade", DbType =

failedStudent.Name + " failed");

}

}

Trang 23

• A function can be used inline as part of a

query (unlike a stored procedure)

– Can return a table or a scalar value

class GetBestGradeDataContext : DataContext {

[ Function (Name = "dbo.GetBestGrade", IsComposable = true )]

public int? GetBestGrade(

[Parameter(Name = "CourseId", DbType = "Int")]

Trang 24

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

Preloading Data – Local Queries

• Controlling relationship preloading:

– Also

DataContext.DeferredLoadingEnabled=true

using (DataContext context ) {

DataLoadOptions dlo = new

DataLoadOptions();

dlo LoadWith<Course> (c => c Grades );

dlo LoadWith<Grade> (g => g Student );

context LoadOptions = dlo;

With preloading: DB trip penalty

and memory footprint

For filtering, also use

DataLoadOptions.AssociateW

ith

Trang 25

Object Tracking

• Object tracking on the DataContext can

be disabled

– Updates won’t be detected, conflicting change

detection will be weaker, identity will not be

guaranteed

• But: better performance for read-only

work, or when implicit updates aren’t

required

DataContext.ObjectTrackingEnabled=false

Trang 26

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

Object Tracking

• Entities can be attached to the data

context

– Useful if upper layers in the applications actively

create data entities

– Can attach with original

• Table<T>.Attach

Trang 27

Review So Far

• Data retrieval and preloading

• Inserts, updates and deletes

• Custom SQL commands (strings)

• Database creation from mapping

• Transactional work

• Optimistic locking (concurrency control)

Trang 28

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

XML Mapping

• True objects-first approach

– E.g if I have WCF data contracts to map to tables

– Minimizes code duplication (Once and Only Once)

– Don’t want LINQ attributes to pollute business entity classes and properties

– Example: http://tinyurl.com/526abw

• Mapping customization without

recompilation

Trang 29

XML Mapping Steps

• Provide XML file with mapping directives

instead of using attributes

< Database Name="CourseManagement“

xmlns="http://schemas.microsoft.com/linqtosql/mapping/2007"> < Table Name="dbo.Courses" Member="Courses">

Trang 30

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

Trang 31

Best Practices

• Keep multiple mapping files and combine them at runtime (with LINQ to XML)

– Facilitates granular source control

– When the entity changes, its mapping file changes

• Embed the mapping file into your

assembly as a resource

Trang 32

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

Inheritance Mapping

• Inheritance is a very non-DB concept

• Multiple ways to model it:

– A single table with combined columns and a

discriminator

– A table for the base and for each derived type

– A table for each derived type with repeated columns from the base type

Trang 33

Discriminator-Based Mapping

[ Table (Name = "Vehicles")]

[ InheritanceMapping (Code = " C ", Type = typeof( Car ))]

[ InheritanceMapping (Code = " T ", Type = typeof( Tank ))] [ InheritanceMapping (Code = " V ", Type = typeof( Vehicle ), IsDefault = true)]

public class Vehicle {

[ Column (IsPrimaryKey = true)]

public int LicenseNumber { get; set; }

[ Column(IsDiscriminator = true ,

DbType = "NChar(1) NOT NULL")]

public string Discriminator { get; set; }

}

public class Car : Vehicle {

[ Column (DbType = "NVarChar(60)")]

public string ModelName { get; set; }

[ Column ]

public DateTime? Sold { get; set; }

} //More types in the samples

Trang 34

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

Querying Inheritance

• The OfType query operator

– The LINQ to SQL query provider translates it to a

WHERE on the discriminator column

Trang 35

Do I Have to Write This by Hand

?

• Visual Studio Designer to the rescue

– SqlMetal also to the rescue

Trang 36

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

Trang 37

• Property access to tables from context

• Partial methods for notifications on the

context and on individual objects

• Events from

INotifyPropertyChanging and

INotifyPropertyChanged

Trang 38

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

Highlights

• Easy customization for Insert, Delete and Update methods to become sprocs

Trang 39

foreach (var avg in averages)

Console.WriteLine("{0} has an average of {1}", avg.Name, avg.Average);

foreach (Student failedStudent in

context GetFailingStudents (78)) {

Console.WriteLine("{0} failed",

failedStudent.Name);

Trang 40

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

Example 2

using (CourseManagementDataContext context =

new CourseManagementDataContext()) {

Grade katesGrade =

(from grade in context.Grades

where grade.Student.Name == "Kate"

select grade).First();

katesGrade PropertyChanging += (o, e) =>

Console.WriteLine(e.PropertyName + " changing"); katesGrade PropertyChanged += (o, e) =>

Trang 41

Example 3

partial class Student {

partial void OnNameChanging (string value) {

partial class CourseManagementDataContext {

partial void UpdateStudent (Student instance) {

Trang 42

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

More Highlights

• Lazy loading

– Use Link<T>

instead of T

• Validation through OnValidate partial

method (on insert, update and delete)

• Debugger visualization

Trang 43

Why Haven’t You Mentioned It Before

!?

• Because the underlying mechanism is

more important than drag-and-drop

• Because the designer doesn’t support

XML mapping (must do it manually)

• Because wizards always require

customization

Trang 44

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

SqlMetal

• An SDK tool for generating DBML, code

and XML mapping files

Trang 45

LINQ to SQL Performance

1 Turn off object tracking for read-only contexts

2 Use compiled queries –

CompiledQuery.Compile

3 Use DataLoadOptions properly

4 Use UpdateCheck.Never if appropriate

5 If possible, select temporary objects instead of

tracked entities (GC and tracking overhead)

6 Use a DataContext per method – do not pool

or share them

LINQ to SQL can be 95% as fast

as Data Readers

http://tinyurl.com/2tkche

Trang 46

© Copyright SELA Software & Education Labs Ltd 14-18 Baruch Hirsch St Bnei Brak 51202 Israel

Chapter Summary

• LINQ to Relational Data

– DataSets, XML via DataSets

Ngày đăng: 12/01/2013, 16:18

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN