Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ha olyan entitásobjektumokat szerializál, mint az Ügyfelek vagy a Rendelések egy ügyfél számára egy hálózaton keresztül, ezek az entitások leválasztva lesznek az adatkörnyezetükről. Az adatkörnyezet már nem követi nyomon a módosításokat vagy más objektumokkal való társításukat. Ez nem probléma, ha az ügyfelek csak az adatokat olvassák. Az is viszonylag egyszerű, hogy az ügyfelek új sorokat vegyenek fel egy adatbázisba. Ha azonban az alkalmazás megköveteli, hogy az ügyfelek frissíthessék vagy törölhessék az adatokat, az entitásokat egy új adatkörnyezethez kell csatolnia a hívás DataContext.SubmitChangeselőtt. Ezenkívül ha optimista egyidejűségi ellenőrzést használ az eredeti értékekkel, akkor az adatbázist is módosítani kell az eredeti entitás és az entitás számára. A Attach
metódusok lehetővé teszik az entitások új adatkörnyezetbe helyezését a leválasztásuk után.
Még ha proxyobjektumokat is szerializál a LINQ helyett az SQL-entitásokhoz, akkor is létre kell készítenie egy entitást az adatelérési rétegen (DAL), és egy újhoz System.Data.Linq.DataContextkell csatolnia, hogy az adatokat elküldhesse az adatbázisnak.
A LINQ–SQL teljesen közömbös az entitások szerializálásával kapcsolatban. A Windows Communication Foundation (WCF) használatával szerializálható osztályok létrehozásához az Object Relational Designer és az SQLMetal eszközök használatával történő használatáról a How to: Make Entities Serializable (Entitások szerializálhatóvá tétele) című témakörben talál további információt.
Feljegyzés
Csak új vagy deszerializált entitásokon hívja meg a Attach
metódusokat. Az entitások csak úgy távolíthatók el az eredeti adatkörnyezetből, ha szerializálják. Ha egy nem gyorsítótárazott entitást próbál egy új adatkörnyezethez csatolni, és az entitás továbbra is késleltetett betöltőkkel rendelkezik az előző adatkörnyezetből, a LINQ és az SQL kivételt fog okozni. Ha egy entitás két különböző adatkörnyezetből származó halasztott betöltőkkel rendelkezik, nem kívánt eredményeket okozhat, amikor beszúrási, frissítési és törlési műveleteket hajt végre az adott entitáson. A halasztott betöltőkkel kapcsolatos további információkért lásd a Késleltetett és az Azonnali betöltés című témakört.
Adatok lekérése
Ügyfélmetódus hívása
Az alábbi példák egy Windows Forms-ügyfél dal-hívásának mintametódus-hívását mutatják be. Ebben a példában a DAL windowsos szolgáltatáskódtárként van implementálva:
Private Function GetProdsByCat_Click(ByVal sender As Object, ByVal e _
As EventArgs)
' Create the WCF client proxy.
Dim proxy As New NorthwindServiceReference.Service1Client
' Call the method on the service.
Dim products As NorthwindServiceReference.Product() = _
proxy.GetProductsByCategory(1)
' If the database uses original values for concurrency checks,
' the client needs to store them and pass them back to the
' middle tier along with the new values when updating data.
For Each v As NorthwindClient1.NorthwindServiceReference.Product _
In products
' Persist to a List(Of Product) declared at class scope.
' Additional change-tracking logic is the responsibility
' of the presentation tier and/or middle tier.
originalProducts.Add(v)
Next
' (Not shown) Bind the products list to a control
' and/or perform whatever processing is necessary.
End Function
private void GetProdsByCat_Click(object sender, EventArgs e)
{
// Create the WCF client proxy.
NorthwindServiceReference.Service1Client proxy =
new NorthwindClient.NorthwindServiceReference.Service1Client();
// Call the method on the service.
NorthwindServiceReference.Product[] products =
proxy.GetProductsByCategory(1);
// If the database uses original values for concurrency checks,
// the client needs to store them and pass them back to the
// middle tier along with the new values when updating data.
foreach (var v in products)
{
// Persist to a list<Product> declared at class scope.
// Additional change-tracking logic is the responsibility
// of the presentation tier and/or middle tier.
originalProducts.Add(v);
}
// (Not shown) Bind the products list to a control
// and/or perform whatever processing is necessary.
}
Közepes szintű implementáció
Az alábbi példa az interfészmetódus implementációját mutatja be a középső szinten. A következő két fő szempontot érdemes megjegyezni:
- A DataContext metódus hatókörében deklarálva van.
- A metódus a tényleges eredmények gyűjteményét adja vissza IEnumerable . A szerializáló végrehajtja a lekérdezést, hogy az eredményeket visszaküldje az ügyfél/bemutató rétegnek. Ha helyileg szeretné elérni a lekérdezési eredményeket a középső szinten, kényszerítheti a végrehajtást a hívással
ToList
vagyToArray
a lekérdezési változóval. Ezután visszaadhatja a listát vagy a tömbötIEnumerable
.
Public Function GetProductsByCategory(ByVal categoryID As Integer) _
As IEnumerable(Of Product)
Dim db As New NorthwindClasses1DataContext(connectionString)
Dim productQuery = _
From prod In db.Products _
Where prod.CategoryID = categoryID _
Select prod
Return productQuery.AsEnumerable()
End Function
public IEnumerable<Product> GetProductsByCategory(int categoryID)
{
NorthwindClasses1DataContext db =
new NorthwindClasses1DataContext(connectionString);
IEnumerable<Product> productQuery =
from prod in db.Products
where prod.CategoryID == categoryID
select prod;
return productQuery.AsEnumerable();
}
Egy adatkörnyezet egy példányának egy "munkaegység" élettartamával kell rendelkeznie. Lazán összekapcsolt környezetben a munkaegység általában kicsi, talán egy optimista tranzakció, beleértve a hívásokat SubmitChanges
is. Ezért az adatkörnyezetet a rendszer a metódus hatókörében hozza létre és helyezi el. Ha a munkaegység üzleti szabályok logikájára irányuló hívásokat tartalmaz, akkor általában meg kell őriznie a példányt az DataContext
egész művelethez. Mindenesetre a DataContext
példányokat nem kívánják hosszú ideig életben tartani tetszőleges számú tranzakcióban.
Ez a metódus termékobjektumokat ad vissza, de nem az egyes termékekhez társított Order_Detail objektumok gyűjteményét. DataLoadOptions Az objektummal módosíthatja ezt az alapértelmezett viselkedést. További információ : Útmutató: A kapcsolódó adatok lekérésének szabályozása.
Adatok beszúrása
Új objektum beszúrásához a bemutatóréteg csak meghívja a középső réteg felületének megfelelő metódusát, és átadja a beszúráshoz szükséges új objektumot. Bizonyos esetekben hatékonyabb lehet, ha az ügyfél csak bizonyos értékeket ad át, és a középső réteg hozza létre a teljes objektumot.
Közepes szintű implementáció
A középső rétegben létrejön egy új DataContext , az objektumot a DataContext metódussal InsertOnSubmit csatolja a rendszer, és az objektumot a rendszer beszúrja, amikor SubmitChanges meghívják. A kivételek, visszahívások és hibafeltételek ugyanúgy kezelhetők, mint bármely más webszolgáltatás-forgatókönyvben.
' No call to Attach is necessary for inserts.
Public Sub InsertOrder(ByVal o As Order)
Dim db As New NorthwindClasses1DataContext(connectionString)
db.Orders.InsertOnSubmit(o)
' Exception handling not shown.
db.SubmitChanges()
End Sub
// No call to Attach is necessary for inserts.
public void InsertOrder(Order o)
{
NorthwindClasses1DataContext db = new NorthwindClasses1DataContext(connectionString);
db.Orders.InsertOnSubmit(o);
// Exception handling not shown.
db.SubmitChanges();
}
Adatok törlése
Ha törölni szeretne egy meglévő objektumot az adatbázisból, a bemutatószint meghívja a középső réteg felületének megfelelő metódusát, és átadja annak másolatát, amely tartalmazza a törölni kívánt objektum eredeti értékeit.
A törlési műveletek optimista egyidejűségi ellenőrzéseket igényelnek, és a törölni kívánt objektumot először az új adatkörnyezethez kell csatolni. Ebben a példában a Boolean
paraméter úgy van beállítva false
, hogy jelezze, hogy az objektum nem rendelkezik időbélyegzővel (RowVersion). Ha az adatbázistábla időbélyegeket hoz létre az egyes rekordokhoz, akkor az egyidejűségi ellenőrzések sokkal egyszerűbbek, különösen az ügyfél esetében. Csak adja meg az eredeti vagy a módosított objektumot, és állítsa a paramétert a Boolean
következőre true
: . Mindenesetre a középső szinten általában szükség van a fogásra.ChangeConflictException További információ az optimista egyidejűségi ütközések kezeléséről: Optimista egyidejűség: Áttekintés.
A társított táblákra idegenkulcs-korlátozásokkal rendelkező entitások törlésekor először törölnie kell a gyűjteményeiben lévő EntitySet<TEntity> összes objektumot.
' Attach is necessary for deletes.
Public Sub DeleteOrder(ByVal order As Order)
Dim db As New NorthwindClasses1DataContext(connectionString)
db.Orders.Attach(order, False)
' This will throw an exception if the order has order details.
db.Orders.DeleteOnSubmit(order)
Try
' ConflictMode is an optional parameter.
db.SubmitChanges(ConflictMode.ContinueOnConflict)
Catch ex As ChangeConflictException
' Get conflict information, and take actions
' that are appropriate for your application.
' See MSDN Article "How to: Manage Change
' Conflicts (LINQ to SQL).
End Try
End Sub
// Attach is necessary for deletes.
public void DeleteOrder(Order order)
{
NorthwindClasses1DataContext db = new NorthwindClasses1DataContext(connectionString);
db.Orders.Attach(order, false);
// This will throw an exception if the order has order details.
db.Orders.DeleteOnSubmit(order);
try
{
// ConflictMode is an optional parameter.
db.SubmitChanges(ConflictMode.ContinueOnConflict);
}
catch (ChangeConflictException e)
{
// Get conflict information, and take actions
// that are appropriate for your application.
// See MSDN Article How to: Manage Change Conflicts (LINQ to SQL).
}
}
Adatok frissítése
Az SQL-hez való LINQ támogatja a frissítéseket ezekben a forgatókönyvekben, amelyekben optimista egyidejűség szerepel:
- Optimista egyidejűség időbélyegek vagy RowVersion-számok alapján.
- Optimista egyidejűség az entitástulajdonságok egy részhalmazának eredeti értékei alapján.
- Optimista egyidejűség a teljes eredeti és módosított entitások alapján.
Az entitásokon frissítéseket vagy törléseket is végrehajthat a kapcsolataival együtt, például egy Ügyfelet és a társított Rendelési objektumok gyűjteményét. Ha módosítja az ügyfelet egy entitásobjektumok és gyermek (EntitySet
) gyűjtemények gráfján, és az optimista egyidejűségi ellenőrzésekhez eredeti értékekre van szükség, az ügyfélnek meg kell adnia ezeket az eredeti értékeket az egyes entitásokhoz és EntitySet<TEntity> objektumokhoz. Ha engedélyezni szeretné az ügyfelek számára, hogy egy metódushívásban kapcsolódó frissítéseket, törléseket és beszúrásokat hajtsanak végre, meg kell adnia az ügyfélnek, hogy jelezze, milyen típusú műveletet kell végrehajtania az egyes entitásokon. A középső rétegben ezután meg kell hívnia a megfelelő Attach metódust, InsertOnSubmitDeleteAllOnSubmit majd InsertOnSubmit( beszúrások nélkül Attach
) minden entitáshoz a hívás SubmitChangeselőtt. A frissítések kipróbálása előtt ne kérjen le adatokat az adatbázisból az eredeti értékek lekéréséhez.
További információ az optimista egyidejűségről: Optimista egyidejűség: Áttekintés. Az optimista egyidejűségi változásütközések feloldásával kapcsolatos részletes információkért tekintse meg a Módosításütközések kezelése című témakört.
Az alábbi példák az egyes forgatókönyveket mutatják be:
Optimista egyidejűség időbélyegekkel
' Assume that "customer" has been sent by client.
' Attach with "true" to say this is a modified entity
' and it can be checked for optimistic concurrency
' because it has a column that is marked with the
' "RowVersion" attribute.
db.Customers.Attach(customer, True)
Try
' Optional: Specify a ConflictMode value
' in call to SubmitChanges.
db.SubmitChanges()
Catch ex As ChangeConflictException
' Handle conflict based on options provided.
' See MSDN article "How to: Manage Change
' Conflicts (LINQ to SQL)".
End Try
// Assume that "customer" has been sent by client.
// Attach with "true" to say this is a modified entity
// and it can be checked for optimistic concurrency because
// it has a column that is marked with "RowVersion" attribute
db.Customers.Attach(customer, true)
try
{
// Optional: Specify a ConflictMode value
// in call to SubmitChanges.
db.SubmitChanges();
}
catch(ChangeConflictException e)
{
// Handle conflict based on options provided
// See MSDN article How to: Manage Change Conflicts (LINQ to SQL).
}
Az eredeti értékek részhalmazával
Ebben a megközelítésben az ügyfél visszaadja a teljes szerializált objektumot a módosítandó értékekkel együtt.
Public Sub UpdateProductInventory(ByVal p As Product, ByVal _
unitsInStock As Short?, ByVal unitsOnOrder As Short?)
Using db As New NorthwindClasses1DataContext(connectionString)
' p is the original unmodified product
' that was obtained from the database.
' The client kept a copy and returns it now.
db.Products.Attach(p, False)
' Now that the original values are in the data context,
' apply the changes.
p.UnitsInStock = unitsInStock
p.UnitsOnOrder = unitsOnOrder
Try
' Optional: Specify a ConflictMode value
' in call to SubmitChanges.
db.SubmitChanges()
Catch ex As Exception
' Handle conflict based on options provided.
' See MSDN article "How to: Manage Change Conflicts
' (LINQ to SQL)".
End Try
End Using
End Sub
public void UpdateProductInventory(Product p, short? unitsInStock, short? unitsOnOrder)
{
using (NorthwindClasses1DataContext db = new NorthwindClasses1DataContext(connectionString))
{
// p is the original unmodified product
// that was obtained from the database.
// The client kept a copy and returns it now.
db.Products.Attach(p, false);
// Now that the original values are in the data context, apply the changes.
p.UnitsInStock = unitsInStock;
p.UnitsOnOrder = unitsOnOrder;
try
{
// Optional: Specify a ConflictMode value
// in call to SubmitChanges.
db.SubmitChanges();
}
catch (ChangeConflictException e)
{
// Handle conflict based on provided options.
// See MSDN article How to: Manage Change Conflicts
// (LINQ to SQL).
}
}
}
Teljes entitásokkal
Public Sub UpdateProductInfo(ByVal newProd As Product, ByVal _
originalProd As Product)
Using db As New NorthwindClasses1DataContext(connectionString)
db.Products.Attach(newProd, originalProd)
Try
' Optional: Specify a ConflictMode value
' in call to SubmitChanges.
db.SubmitChanges()
Catch ex As Exception
' Handle potential change conflict in whatever way
' is appropriate for your application.
' For more information, see the MSDN article
' "How to: Manage Change Conflicts (LINQ to
' SQL)".
End Try
End Using
End Sub
public void UpdateProductInfo(Product newProd, Product originalProd)
{
using (NorthwindClasses1DataContext db = new
NorthwindClasses1DataContext(connectionString))
{
db.Products.Attach(newProd, originalProd);
try
{
// Optional: Specify a ConflictMode value
// in call to SubmitChanges.
db.SubmitChanges();
}
catch (ChangeConflictException e)
{
// Handle potential change conflict in whatever way
// is appropriate for your application.
// For more information, see the MSDN article
// How to: Manage Change Conflicts (LINQ to SQL)/
}
}
}
Gyűjtemény frissítéséhez hívja meg ahelyettAttachAll, hogy a Attach
.
Várt entitástagok
Ahogy korábban említettem, a metódusok meghívása Attach
előtt csak az entitásobjektum bizonyos tagjait kell beállítani. A beállításhoz szükséges entitástagok számára meg kell felelniük a következő feltételeknek:
- Legyen az entitás identitásának része.
- Várhatóan módosítani kell.
- Legyen időbélyeg, vagy az attribútuma UpdateCheck mellett valami
Never
másra is legyen állítva.
Ha egy tábla időbélyeget vagy verziószámot használ az optimista egyidejűség-ellenőrzéshez, a hívás Attachelőtt be kell állítania ezeket a tagokat. A tag optimista egyidejűség-ellenőrzésre van kijelölve, ha a IsVersion tulajdonság igaz értékre van állítva az Oszlop attribútumon. A kért frissítések csak akkor lesznek elküldve, ha a verziószám vagy az időbélyeg értéke megegyezik az adatbázisban.
Az optimista egyidejűség-ellenőrzés során egy tagot is használ a rendszer, ha a tag nem lett UpdateCheck beállítva Never
. Az alapértelmezett érték az, Always
ha nincs megadva más érték.
Ha a szükséges tagok bármelyike hiányzik, ChangeConflictException a rendszer a (nem található vagy módosított sor) során SubmitChanges adódik.
Állapot
Miután egy entitásobjektumot csatolt a DataContext példányhoz, az objektum állapotban PossiblyModified
van. Egy csatolt objektumot háromféleképpen lehet megfontolni Modified
.
Csatolja módosítatlanként, majd módosítsa közvetlenül a mezőket.
Csatolja az Attach aktuális és az eredeti objektumpéldányokat tartalmazó túlterheléshez. Ez régi és új értékekkel látja el a változáskövetőt, így automatikusan tudni fogja, hogy mely mezők változtak.
Csatolja a Attach túlterheléshez, amely egy második logikai paramétert vesz igénybe (igaz értékre van állítva). Ez azt fogja mondani a változáskövetőnek, hogy fontolja meg az objektum módosítását anélkül, hogy eredeti értékeket kellene megadnia. Ebben a megközelítésben az objektumnak verzió/időbélyeg mezővel kell rendelkeznie.
További információ: Objektumállapotok és változáskövetés.
Ha egy entitásobjektum már előfordul az azonosító-gyorsítótárban ugyanazzal az identitással, mint a csatolt objektum, akkor a függvény egy DuplicateKeyException műveletet alkalmaz.
Ha objektumkészlettel IEnumerable
csatlakozik, DuplicateKeyException a rendszer egy már meglévő kulccsal jelenik meg. A fennmaradó objektumok nincsenek csatolva.