16
Realtime™ Development Framework applied to LINQ (.NET Language-Integrated Query) LINQ เปลี่ยนชื่อมาจาก DLINQ และเป็น ORM (Object- Relational Mapping) ที่จะ Implement ลงใน Visual Studio 2008 เป็นเทคนิคในการเขียนโปรแกรมเพื่อทาการแปลงโครงสร้าง (mapping) จาก Relational Database ให ้มาอยู่ในรูปของ OO โดย Type ทางฝั่ง Database และทางฝั่งของ OO มีความเข ้ากัน ได ้ nw 12/13/2007

Realtime Linq Mapper

Embed Size (px)

Citation preview

Page 1: Realtime Linq Mapper

Realtime™ Development Framework applied to LINQ (.NET Language-Integrated Query) LINQ เปลยนชอมาจาก DLINQ และเปน ORM (Object-

Relational Mapping) ทจะ Implement ลงใน Visual Studio 2008 เปนเทคนคในการเขยนโปรแกรมเพอท าการแปลงโครงสราง

(mapping) จาก Relational Database ใหมาอยในรปของ OO โดย Type ทางฝง Database และทางฝงของ OO มความเขากน

ได nw 12/13/2007

Page 2: Realtime Linq Mapper

Realtime™ Development Framework applied to LINQ (.NET Language-Integrated Query)

LINQ เปลยนชอมาจาก DLINQ และเปน ORM (Object-Relational Mapping) ทจะ Implement ลงใน

Visual Studio 2008 เปนเทคนคในการเขยนโปรแกรมเพอท าการแปลง โครงสราง (mapping) จาก Relational

Database ใหมาอยในรปของ OO โดย Type ทางฝง Database และทางฝงของ OO มความเขากนได

โครงสรางของ LINQ ประกอบดวยสวนตางๆ ดงน

LINQ to Objects เพอใช LINQ ตดตอกบ Object อนๆ

LINQ to Datasets, LINQ to SQL, LINQ to Entities ใชในการตดตอกบ Relational Database

LINQ to XML ใชในการตดตอกบ XML Document โดยเฉพาะ

ใน Realtime™ Development Framework จะอมพลเมนตเฉพาะ LINQ to SQL เทานน โดยสราง Class

ออกมาแทน Object ตางๆ ใน Database เชน Table, View และสราง Function, Method ตางๆ เพอใชในการ

Select, Insert, Delete, Update ขอมลตางๆใน Database เรยกวา Virtual Object Database ซงคอมไพลและ

แยกเกบไวเปน Library ในรป DLL File การน า LINQ to SQL มาใชงานจะชวยแกปญหาตางๆ กลาวคอ เดมท

SQL Statement ทอยในรปตวแปร string เพอทน าไป Execute ใน database แลวรบคาท Return กลบมาใสใน

Result Set ตางๆ เชน DataTable หรอ DataReader ซงชดค าสง SQL ดงกลาวยงยากตอการตรวจสอบความ

ผดพลาด และไมม IntelliSense มาชวยในการเขย น เราจะรวาการเขยนค าสงนนผดพลาดกตอเมอมนไดถก

Execute ลงใน Database แลว และมการ Throw Database Exception นนกลบขนมา จากปญหาเหลานตว

LINQ จะชวยใหเราสามารถตรวจสอบขอผดพลาดของการเขยน Query ในระดบ Compile time นอกจากนนยงม

Intellisence มาชวยใหพมพผดนอยลงอกดวย

Database

• NVarChar

Mapper

• String

Page 3: Realtime Linq Mapper

Mapping Table ของ LINQ to SQL

จะมลกษณะดงภาพดานลางโดยทฝงซายจะแทนโครงสรางของ Database และทางฝงขวาคอ OO

สวนทเพมเตมขนมา จาก ORM เวอรชนเดม คอ DataContext ซงเสมอนเปนทอสงหลกทใชในการดง

ขอมลจาก Database และท าการสงขอมลทมการ เปลยนแปลงกลบลงไปยง Database เราสามารถใช DataContext ไดในลกษณะเดยวกน กบ ADO.NET Connection ทวไป (เชน SqlConnection ซงสามารถระบ

Connection String ไดโดยตรงหรอผาน app.config) หนาทหลกของ DataContext คอ

1. สราง Database Connection 2. แปลง LINQ Query Syntax ใหเปน SQL Statement เพอเตรยม Execute

3. แปลง Object ทถก Query ขนมา ใหกลบลงไปยง Database ในรปแบบท Database Modeling

(.dbml) ไดท าการ Mapping เขามา เชน Table, Stored Procedure เปนตน.

วงจรการท างานของ LINQ To SQL

1. สราง LINQ Query Syntax ส าหรบกระท ากบฐานขอมลตามตองการ

2. LINQ Query Syntax จะถกแปลงเปน SQL Statement 3. SQL Statement จะถก Execute ในลกษณะการ Execute Database ทวไป โดยสงขอมลกลบมาใน

รปแบบ Datatype ของ Database เชน Row 4. ขอมลทคนกลบมาจะถกแปลงใหอยในรป ObjectType ตามท Mapping Table ระบ

5. กรณเปนการปรบเปลยน Property หรอเพม Entity Object ตางๆ จะเรมตนโดยการเรยก Method SubmitChanges() ใน Class ชอ DataContext

6. แปลงกลม Entity หรอ Property ทระบจะถกแปลงเปน SQL Statement ในรปของ DML หรอ Stored

Procedure กลบไปยง SQL Server แลวประมวลผลในลกษณะเดยวกน

Page 4: Realtime Linq Mapper

Implicitly typed local variables

คอการใช keyword var เพอประกาศตวแปร หรอสมาชกแบบอนๆ โดยไมจ าเปนตองก าหนด datatype

ทชดเจน ตวแปรทถกสรางขนอาจรองรบ datatype ประเภทไหนกได

การใช implicitly type local variable มลกษณะคลายกบ Object Type แตตางกนตรงท var เปน

Primitive Type (ไมตองม pointer ส าหรบชต าแหนงใน memory) ท าใหการเรยกใช ไมตองมการ cast Pointer Type กลบไปมา สวนขอเสยของการใช variant (var) คอใชหนวยความจ ามากและไมเปน strong typed ซงเปน

สงส าคญใน .Net ตวอยางการประกาศก าหนดไดดงน

var foo = 0.8;

การก าหนดคาครงแรกของตวแปร จะเปนบรรทดทเรมระบให Compiler รวาเปนตวแปรประเภทใดแน นอกจากนเรายงสามารถใช variant รวมกบ object initialization ไดดวย

Anonymous types

เปนคณสมบตเรมมใชใน C#3.0 ชวยอ านวยความสะดวกในการสราง และก าหนดคาเรมตน ใหแก object

โดยไมตองก าหนด type ท าใหการเขยนโคด ยดหยนขนเราสมารถสรางและก าหนดคาเรมตนให object ทสราง

จากคลาสได โดยอาศย object initialization ไดดงน

var mySudent = new Student{ name = "Pravit", Age = 45, address = "109/20"

};

class Student

{

public string name;

public string address;

int age;

public int Age

{

get { return age; }

set { age = value; }

}

}

จากโคดขางตนเราสงเกตไดวาเราก าหนดให object myStudent ม type เปน var ซงเปน implicit type local

variables เมอ compile แลว myStudent จะไดรบ type ทแทจรงคอ Student เราสามารถเขยนโคดไดอก

ลกษณะเพอความยดหยนของ Anonymous types เราสามารถก าหนดคาเรมตนใหกบ object ไดดงน

Page 5: Realtime Linq Mapper

var mySudent = new { name = "Pravit", Age = 45, address = "109/29" };

โปรดสงเกตวาเราไดละชอ constructor ออกไปซงมความหมายวาไมไดระบ type ทใชในการก าหนดคาเรมตน

ดงนนเราจงไมรวา object myStudent เปน type อะไรแนแตโปรแกรมกท างานโดยไม error เพราะ compiler จะ

สราง type ใหเราขณะคอมไพล

ขอสรป Anonymous types

ชวยในการสราง object โดยไมตองระบ type

Syntax คลาย object initializes แตไมระบ type

มกใชกบ Implicitly typed local avariables

Complier จะสราง type ใหขณะ complie (late binding)

Implicitly typed arrays

เปนคณสมบตเรมใชใน C#3.0 ชวยอ านวยความสะดวกในการประกาศ และก าหนดคาเรมตนใหแก array

โดยไมตองก าหนด type, size and dimension ท าใหการเขยนโคดยดหยนขน

เดมทใน C# 2.0 เราตองประกาศและก าหนดคาเรมตนใหแก array โดยค าสงตอไปน

int[] arr = new int[] { 1, 2, 3, 4 };

แตใน C#3.0 เราสามารถเขยนไดโดยค าสงตอไปน

var arr = new[] { 1, 2, 3, 4 };

โปรดสงเกตวาเราไมไดก าหนด type เมอ compile arr จะม data type เปน int

ขอสรป Implicitly typed arrays

ชวยใหสราง array โดยไมตองระบ type

ชวยใหสราง syntax คลายการนยาม array ธรรมดาแตไมระบ type

มกจะใชรวมกบ implicitly type local variables

Compiler จะก าหนด type ใหขณะ compile

Lambda Expression

เปนคณลกษณะทเพมขนใน C# 3.0 ท าให anonymous method ของ C# 2.0 กลายเปนสงทลาสมย

Lambda Expression มประโยชนในการเขยนโคดทเกยวของกบ delegate, DLINQ และ expression tree และ

ชวยในการเขยนโคดใหกระชบตามแบบในภาษาตระกล c และสงางามตามแบบ C# พจารณาจากโคดตอไปน

x => x > 10

นคอรปแบบในรปสามญทสด มนคอนพจน Boolean ทมคาเปนจรงหาก x มคามากกวา 10 เราสามารถใชภาษา

LINQ ไดหากใช DLINQ (DLINQ คอภาษาใหมโดยใช LINQ ไดถกผนวกเปนหนงใน C# 3.0) เมอ compile แลว

มกจะพบ Lambda Expression ปรากฏอยดวย โปรดพจารณาตวอยาง DLINQ ดงตอไปน

Page 6: Realtime Linq Mapper

var myQ =

from myTable in orders, c in customers

where ( myTable.ShipCity == "London") &&

( myTable.CustomerID == c.CustomerID)

select new

{

myTable.OrderDate,

c.CompanyName,

c.ContactTitle,

c.ContactName

};

โคดขางบนคอการสบคนขอมลดวยภาษา DLINQ ในโคด นจะเหนวามตารางสองตาราง อนแรกเปน object ชอ

myTable ซงอยภายใน object collection ชอ order อกตารางชอ c อยภายในฐานขอมลชอ customers เราใช ภาษา DLINQ เพอสบคนขอมลพรอมๆ กนทงสองตารางโคดนเมอคอมไพลแลวจะเปนดงน

var myQ = orders

.Where(myTable => myTable.ShipCity == "London")

.SelectMany(myTable => customers

.Where(c => myTable.CustomerID == c.CustomerID)

.Select(c => new

{

myTable.OrderDate,

c.CompanyName,

c.ContactTitle,

c.ContactName

}));

ในโคดนมสวนทเปน Lambda Expression อย 2 แหงคอ

myTable => myTable.ShipCity == "London"

และ c => myTable.CustomerID == c.CustomerID

ในสองบรรทดนเราจะเหนวา Lambda Expression อยในรปแบบ Parameter => Expression โดยบรรทดแรก

Parameter คอ myTable สวน expression คอ myTable.ShipCity == "London" C# 3.0 ไดนยาม generic delegate ไวใหแลวสวนหนงซงมรปแบบดงน

delegate T Func<A, T>(A param)

delegate T Func<A0, A1, T>(A0 param0, A1 param1)

delegate T Func<A0, A1, A2, T>(A0 param0, A1 param1, A2 param2)

delegate T Func<A0, A1, A2, A3, T>(A0 param0, A1 param1, A2 param2, A3

param3)

ท าใหเราอาจนยาม Lambda Expression ใดๆ โดยไมตองนยาม delegate กอนเพยงใชงานตามรปแบบทนยามไว แลวดงแสดงขางบน ยกตวอยางเชน Lampda Expression เพอตรวจสอบเลขคมดงน

Func<int, bool> isEven = i => (i&1) == 0

ขอสรปเรอง Lambda Expression คอคณลกษณะทเพมขนใน C#3.0 เพอใชแทน anonymous method ใน C#2.0

ท าใหนยาม delegate ไดกระชบขน

ใชรวมกบภาษา LINQ

Page 7: Realtime Linq Mapper

Query Expression

Query syntax ตองเรมตนดวย from และ ลงทายดวย select or group ระหวาง from และ select or

group สามารถบรรจส งใดสงหนงดงน where, orderby, join, let สามารถใช keyword into ส าหรบผลการ join

หรอ group ได

ตวอยางการใช Query expression เบองตน โดยใชกบ List ซงยงไมไดตอกบฐานขอมล

ก าหนดให var scores = new[] { 90, 71, 82, 93, 75, 82 }; List<City> cities = new List<City>();

List<Country> countries = new List<Country>();

public class Country

{

public string Name { get; set; }

public int Area { get; set; }

public List<City> City { get; set; }

}

public class City

{

public int Population { get; set; }

}

Query variable

วธการหาคะแนนมากกวา 80 และเรยงล าดบ จากมากไปหานอย

IEnumerable<int> scoreQuery =

from score in scores

where score > 80

orderby score descending

select score;

output = 93 90 82 82

วธการหาคะแนนสงสด

int highestScore =

(from score in scores

select score)

.Max();

หรอท าการแบงกลมควรออกกอนดงน

IEnumerable<int> scoreQuery =

from score in scores

select score;

int highScore = scoreQuery.Max();

output = 93

วธการหาCity Population > 1000

Page 8: Realtime Linq Mapper

//Query syntax

IEnumerable<City> queryMajorCities =

from city in cities

where city.Population > 1000

select city;

หรอ

// Method-based syntax

IEnumerable<City> queryMajorCities2 = cities.Where(c => c.Population >

1000);

วธการหา City ใน country ท Population > 1000 IEnumerable<City> largeCityList =

from country in countries

from city in country.City

where city.Population > 1000

select city;

Syntax ตางๆ ใน query expression

Explicitly and Implicit Typing of Query Variables

// Use of var is optional here and in all queries.

// queryCities is an IEnumerable<City> just as

// when it is explicitly typed.

var queryCities =

from city in cities

where city.Population > 100

select city;

Ending a Query Expression

Select with group by

var queryCountryGroups =

from country in countries

group country by country.Name[0];

Select with order by

IEnumerable<Country> sortedQuery =

from country in countries

orderby country.Area

select country;

var queryNameAndPop =

from country in countries

select new { Name = country.Name, Pop = country.Population

};

Page 9: Realtime Linq Mapper

Continuations with "into" var percentileQuery =

from country in countries

let percentile = (int)country.Area / 2

group country by percentile into countryGroup

where countryGroup.Key >= 20

orderby countryGroup.Key

select countryGroup;

where Clause

IEnumerable<City> queryCityPop =

from city in cities

where city.Population < 200000 && city.Population > 100000

select city;

order by Clause

IEnumerable<Country> querySortedCountries =

from country in countries

orderby country.Area > 500000, country.Area descending

select country;

Join Clause

var categoryQuery =

from cat in categories

join prod in products on cat equals prod.Category

select new { Category = cat, Name = prod.Name };

Let Clause

IEnumerable<int> queryScr =

from scr in scores

let scMin = scr-10

select scMin;

output = 80, 61, 72, 83, 65, 72

Subqueries in a Query Expression

var queryGroupMax =

from student in students

group student by student.GradeLevel into studentGroup

select new

{

Level = studentGroup.Key,

HighestScore =

(from student2 in studentGroup

select student2.Scores.Average())

.Max()

};

Page 10: Realtime Linq Mapper

ตวอยางการ Join ทประกอบดวย inner join, group join, left outer join

class JoinDemonstration

{

#region Data

class Product

{

public string Name { get; set; }

public string CategoryID { get; set; }

}

class Category

{

public string Name { get; set; }

public string ID { get; set; }

}

// Specify the first data source.

List<Category> categories = new List<Category>()

{

new Category(){Name="Beverages", ID="001"},

new Category(){ Name="Condiments", ID="002"},

new Category(){ Name="Vegetables", ID="003"},

new Category() { Name="Grains", ID="004"},

new Category() { Name="Fruit", ID="005"}

};

// Specify the second data source.

List<Product> products = new List<Product>()

{

new Product{Name="Cola", CategoryID="001"},

new Product{Name="Tea", CategoryID="001"},

new Product{Name="Mustard", CategoryID="002"},

new Product{Name="Pickles", CategoryID="002"},

new Product{Name="Carrots", CategoryID="003"},

new Product{Name="Bok Choy", CategoryID="003"},

new Product{Name="Peaches", CategoryID="005"},

new Product{Name="Melons", CategoryID="005"},

new Product{Name="CityCar", CategoryID="008"},

new Product{Name="Toyota", CategoryID="008"},

};

#endregion

static void Main(string[] args)

{

JoinDemonstration app = new JoinDemonstration();

app.InnerJoin();

app.GroupJoin();

app.GroupInnerJoin();

app.GroupJoin3();

app.LeftOuterJoin();

app.LeftOuterJoin2();

// Keep the console window open in debug mode.

Console.WriteLine("Press any key to exit.");

Console.ReadKey();

}

void InnerJoin()

{

Page 11: Realtime Linq Mapper

// Create the query that selects

// a property from each element.

var innerJoinQuery =

from category in categories

join prod in products on category.ID equals prod.CategoryID

select new { CategoryID = category.ID,CategoryName =

category.Name, Product = prod.Name };

Console.WriteLine("InnerJoin:");

// Execute the query. Access results

// with a simple foreach statement.

foreach (var item in innerJoinQuery)

{

Console.WriteLine("{0} {1} {2}",

item.Product,item.CategoryName, item.CategoryID);

}

Console.WriteLine("InnerJoin: {0} items in 1 group.",

innerJoinQuery.Count());

Console.WriteLine(System.Environment.NewLine);

}

void GroupJoin()

{

// This is a demonstration query to show the output

// of a "raw" group join. A more typical group join

// is shown in the GroupInnerJoin method.

var groupJoinQuery =

from category in categories

join prod in products on category.ID equals prod.CategoryID

into prodGroup

select prodGroup;

// Store the count of total items (for demonstration only).

int totalItems = 0;

Console.WriteLine("Simple GroupJoin:");

// A nested foreach statement is required to access group

items.

foreach (var prodGrouping in groupJoinQuery)

{

Console.WriteLine("Group:");

foreach (var item in prodGrouping)

{

totalItems++;

Console.WriteLine(" {0,-10}{1}", item.Name,

item.CategoryID);

}

}

Console.WriteLine("Unshaped GroupJoin: {0} items in {1} unnamed

groups", totalItems, groupJoinQuery.Count());

Console.WriteLine(System.Environment.NewLine);

}

Page 12: Realtime Linq Mapper

void GroupInnerJoin()

{

var groupJoinQuery2 =

from category in categories

orderby category.ID

join prod in products on category.ID equals prod.CategoryID

into prodGroup

select new

{

Category = category.Name,

Products = from prod2 in prodGroup

orderby prod2.Name

select prod2

};

//Console.WriteLine("GroupInnerJoin:");

int totalItems = 0;

Console.WriteLine("GroupInnerJoin:");

foreach (var productGroup in groupJoinQuery2)

{

Console.WriteLine(productGroup.Category);

foreach (var prodItem in productGroup.Products)

{

totalItems++;

Console.WriteLine(" {0,-10} {1}", prodItem.Name,

prodItem.CategoryID);

}

}

Console.WriteLine("GroupInnerJoin: {0} items in {1} named

groups", totalItems, groupJoinQuery2.Count());

Console.WriteLine(System.Environment.NewLine);

}

void GroupJoin3()

{

var groupJoinQuery3 =

from category in categories

join product in products on category.ID equals

product.CategoryID into prodGroup

from prod in prodGroup

orderby prod.CategoryID

select new { Category = prod.CategoryID, ProductName =

prod.Name };

//Console.WriteLine("GroupInnerJoin:");

int totalItems = 0;

Console.WriteLine("GroupJoin3:");

foreach (var item in groupJoinQuery3)

{

totalItems++;

Console.WriteLine(" {0}:{1}", item.ProductName,

item.Category);

}

Console.WriteLine("GroupJoin3: {0} items in 1 group",

totalItems, groupJoinQuery3.Count());

Console.WriteLine(System.Environment.NewLine);

}

void LeftOuterJoin()

{

Page 13: Realtime Linq Mapper

// Create the query.

var leftOuterQuery =

from category in categories

join prod in products on category.ID equals prod.CategoryID

into prodGroup

select prodGroup.DefaultIfEmpty(new Product() { Name =

"Non", CategoryID = category.ID });

// Store the count of total items (for demonstration only).

int totalItems = 0;

Console.WriteLine("Left Outer Join:");

// A nested foreach statement is required to access group

items

foreach (var prodGrouping in leftOuterQuery)

{

Console.WriteLine("Group:", prodGrouping.Count());

foreach (var item in prodGrouping)

{

totalItems++;

Console.WriteLine(" {0,-10}{1}", item.Name,

item.CategoryID);

}

}

Console.WriteLine("LeftOuterJoin: {0} items in {1} groups",

totalItems, leftOuterQuery.Count());

Console.WriteLine(System.Environment.NewLine);

}

void LeftOuterJoin2()

{

// Create the query.

var leftOuterQuery2 =

from category in categories

join prod in products on category.ID equals prod.CategoryID

into prodGroup

from item in prodGroup.DefaultIfEmpty()

select new { Name = item == null ? "Nothing!" : item.Name,

CategoryID = category.ID };

Console.WriteLine("LeftOuterJoin2: {0} items in 1 group",

leftOuterQuery2.Count());

// Store the count of total items

int totalItems = 0;

Console.WriteLine("Left Outer Join 2:");

// Groups have been flattened.

foreach (var item in leftOuterQuery2)

{

totalItems++;

Console.WriteLine("{0,-10}{1}", item.Name,

item.CategoryID);

}

Console.WriteLine("LeftOuterJoin2: {0} items in 1 group",

totalItems);

}

}

Page 14: Realtime Linq Mapper

MapperDataContext : DataContext

MapperDataContext เปนคลาสจดการฐานขอมลท Linq Mapper เรยกใชงาน โดยจะถกสรางใหแตละ Identity ทเขาสระบบผาน Realtime™ Development Framework : eFx ซงสามารถเรยกใชงานไดดงน

MapperDataContext mx;

mx = RuntimeMonitor.GetObservor().GetCurrentDataContext();

ค านยาม Realtime™ Development Framework : eFx

Realtime™ Development Environment : RTDE

ตวอยางการใชงาน

การเพมขอมล EcUser ecUsr = new EcUser();

ecUsr.ClientNo = "0001";

ecUsr.ClientNoOwner = "0001";

ecUsr.ClientTypeNo = "01";

ecUsr.UserName = "[email protected]";

ecUsr.UserPassword = "l07WGW0fkXGZ4E14sGyfvw";

ecUsr.UserStatus = "1";

ecUsr.UserCreateDate = DateTime.Now;

ecUsr.ContactNo = "101049";

try

{

mx.GetTable<EcUser>().InsertOnSubmit(ecUsr);

mx.SubmitChanges();

}

catch(Exception ex)

{

string exp = ex.ToString();

}

หมายเหต

เราสามารถ insert ขอมลแบบ collection ไดโดยใช method ชอ InsertAllOnSubmit() ดง

ตวอยางตอไปน

mx.GetTable<EcUser>().InsertAllOnSubmit(EcUserCollection ecUsrCollection);

Page 15: Realtime Linq Mapper

การแกไขขอมล var usrCcllection =

from usr in mx.GetTable<EcUser>()

where

usr.ClientNoOwner == "0001" &&

usr.ClientTypeNo == "01" &&

usr.ClientNo == "0001" &&

usr.ContactNo == "101049" &&

usr.UserName == "[email protected]"

select usr;

EcUser ecUsr = usrCcllection.ToList<EcUser>()[0];

ecUsr.UserStatus = "2";

ecUsr.UserCreateDate = DateTime.Now.AddDays(30);

try

{

mx.SubmitChanges();

}

catch (Exception ex)

{

string exp = ex.ToString();

} หมายเหต

เราสามารถ update ขอมลแบบ collection ไดโดยใช method ชอ InsertAllOnSubmit() ดง

ตวอยางตอไปน mx.GetTable<EcUser>().InsertAllOnSubmit(EcUserCollection ecUsrCollection); การลบขอมล var usrCcllection =

from usr in mx.GetTable<EcUser>()

where

usr.ClientNoOwner == "0001" &&

usr.ClientTypeNo == "01" &&

usr.ClientNo == "0001" &&

usr.ContactNo == "101049" &&

usr.UserName == "[email protected]"

select usr;

EcUser ecUsr = usrCcllection.ToList<EcUser>()[0];

ecUsr.UserStatus = "2";

ecUsr.UserCreateDate = DateTime.Now.AddDays(30);

try

{

mx.GetTable<EcUser>().DeleteOnSubmit(ecUsr);

mx.SubmitChanges();

}

catch (Exception ex)

{

string exp = ex.ToString();

} หมายเหต

เราสามารถ Delete ขอมลแบบ collection ไดโดยใช method ชอ DeleteAllOnSubmit()

ดงตวอยางตอไปน mx.GetTable<EcUser>().DeleteAllOnSubmit(EcUserCollection ecUsrCollection);

Page 16: Realtime Linq Mapper

System Requirement

- Microsoft Framework 3.0 or higher

DLL Add-On

- ExtensionCore.dll

Namespace Declaration

- eCenter.Extensions - eCenter.Utilities.Runtime

- eCenter.Data.Linq - eCenter.Data.Mapper.Extensions

- System.Linq - System.Xml.Linq

- System.Data.Linq