private void BindProductsGrid()
{
NorthwindDataContext db = new NorthwindDataContext();
var products = from p in db.Products
where p.Category.CategoryName == "Beverages"
select p;
gvNorthwind.DataSource = products;
gvNorthwind.DataBind();
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindProductsGrid();
}
}
NorthwindDataContext db = new NorthwindDataContext(); var product = db.Products.Single(p => p.ProductName == "Chai"); product.UnitPrice = 2; //ori 18 product.UnitsInStock = 4; //ori 39 db.SubmitChanges(); BindProductsGrid();
We vragen met de extensionmethode Single één enkel Product op.
De eigenschap UnitPrice en UnitsInStock worden aangepast.
De methdoe SubmitChanges van de DataContext zorgt ervoor dat het vereiste update-statement in SQL wordt aangemaakt en naar de database-engine wordt gestuurd.
In de profiler zien we het volgende:
Linq to SQL houdt via de DataContext bij welke entities er werden gewijzigd.
Bij het uitvoeren van de methode SubmitChanges worden alle bijgehouden wijzigingen weggeschreven naar de database.
NorthwindDataContext db = new NorthwindDataContext();
var products = from p in db.Products
where p.Category.CategoryName == "Beverages"
where p.ReorderLevel == 25
select p;
foreach (Product p in products)
{
p.ReorderLevel = 23;
}
db.SubmitChanges();
BindProductsGrid();
Nu worden dus alle producten die we vroeger opnieuw bestelden wanneer er maar 25 stuks meer in vooraad waren, aangevuld bij 23.
Er waren drie producten uit de categorie 'Beverages' met een ReoderLevel van 25, er werden dus drie updates uitgevoerd.
NorthwindDataContext db = new NorthwindDataContext(); Product nieuwProduct = new Product(); nieuwProduct.ProductName = "Cécémel on the rocks"; nieuwProduct.UnitPrice = 3; nieuwProduct.UnitsInStock = 12; nieuwProduct.ReorderLevel = 10; nieuwProduct.CategoryID = 1; db.Products.InsertOnSubmit(nieuwProduct); db.SubmitChanges(); BindProductsGrid();
NorthwindDataContext db = new NorthwindDataContext();
var product = db.Products.Where(p => p.ProductName.StartsWith("Cécé")).Single();
db.Products.DeleteOnSubmit(product);
db.SubmitChanges();
BindProductsGrid();
Voor het verwijderen van een aantal producten kan je DeleteAllOnSubmit gebruiken
Linq to SQL is in staat updates, inserts en deletes uit te voeren en hierbij hebruik te maken van de associations (relaties) die in het model zijn aangegeven.
NorthwindDataContext db = new NorthwindDataContext();
Product nieuwProduct = new Product();
nieuwProduct.ProductName = "Cécémel on the rocks";
nieuwProduct.UnitPrice = 3;
nieuwProduct.UnitsInStock = 12;
nieuwProduct.ReorderLevel = 10;
nieuwProduct.Category = db.Categories.Where(c => c.CategoryName == "Beverages").Single();
db.Products.InsertOnSubmit(nieuwProduct);
db.SubmitChanges();
BindProductsGrid()
In de profiler zien we dat Linq nu eerst de categoriegegevens voor de categorie "Beverages" ophaalt:
Linq to SQL gaat tal van database-instellingen overnemen wanneer data ingevoerd wordt:
Meestal is de automatische validatie die gebeurt door het databaseschema te interpreteren niet voldoende.
Sommige controles, zoals constraints op tabellen worden niet automatisch gedaan: op de tabel Products vinden we op databaseniveau een constraint voor de kolom ReorderLevel:
NorthwindDataContext db = new NorthwindDataContext();
var products = from p in db.Products
where p.Category.CategoryName == "Beverages"
where p.ReorderLevel == 23
select p;
foreach (Product p in products)
{
p.ReorderLevel = -2;
}
db.SubmitChanges();
BindProductsGrid();
Het is mogelijk op Linq to SQL niveau aangepaste validatie te voorzien.
[Column(Storage="_ReorderLevel", DbType="SmallInt")] public System.NullableReorderLevel { get { return this._ReorderLevel; } set { if ((this._ReorderLevel != value)) { this.OnReorderLevelChanging(value); this.SendPropertyChanging(); this._ReorderLevel = value; this.SendPropertyChanged("ReorderLevel"); this.OnReorderLevelChanged(); } } }
Hier leren we dat een methode OnReorderLevelChanging wordt aangeroepen vóór de data wordt aangepast.
De methode OnReoderLevelChanging is eigenlijk een partial method zonder inhoud, het is de bedoeling dat wij hier een uitbreidingspunt vinden voor onze eigen validatie.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NorthwindDAL
{
public partial class Product
{
partial void OnReorderLevelChanging(short? value)
{
if (value < 0)
throw new Exception("ReorderLevel mag niet negatief zijn");
}
}
}
Je kan hierbij handig gebruik maken van Intellisense:
try { NorthwindDataContext db = new NorthwindDataContext(); var products = from p in db.Products where p.Category.CategoryName == "Beverages" where p.ReorderLevel == 23 select p; foreach (Product p in products) { p.ReorderLevel = -2; } db.SubmitChanges(); BindProductsGrid(); } catch (Exception ex) { lblError.Text = ex.Message; }
Wanneer bijvooebeeld de waarde van twee eigenschappen moet vergelijken kan je dat niet meer doen door de partial method OnPropertyChanging te implementeren.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace NorthwindDAL
{
public partial class Product
{
partial void OnReorderLevelChanging(short? value)
{
if (value < 0)
throw new Exception("ReorderLevel mag niet negatief zijn");
}
partial void OnValidate(System.Data.Linq.ChangeAction action)
{
if (UnitPrice > ReorderLevel)
throw new Exception("Unitprice > Reorderlevel, dat mag niet!");
}
}
}
Soms wil je bepaalde code laten uitvoeren wanneeer de gebruiker een element update, insert of delete.
Je wil bijvoorbeeld een controle doen los van het element dat je update, je wil data loggen, backuppen, ...
Linq to SQL biedt je de mogelijkheid om de methoden UpdateEntity, InsertEntity en DeleteEntity (waarbij je Entity vervangt door je eigen klassenaam) in de DataContext-klasse te voorzien.
using System.Text; using System.Diagnostics; namespace NorthwindDAL { public partial class NorthwindDataContext { partial void UpdateProduct(Product instance) { Debug.Print("Update voor product: " +instance.ProductName + ": RL = " + instance.ReorderLevel.ToString()); Debug.Print("Voor update product - controles"); //Doe de eigenlijke update this.ExecuteDynamicUpdate(instance); Debug.Print("Na update product - logging"); } } }
try
{
NorthwindDataContext db = new NorthwindDataContext();
var products = from p in db.Products
where p.Category.CategoryName == "Beverages"
where p.ReorderLevel == 23
select p;
foreach (Product p in products)
{
p.ReorderLevel = 24;
}
db.SubmitChanges();
BindProductsGrid();
}
catch (Exception ex)
{
lblError.Text = ex.Message;
}
Update voor product: Chang: RL = 24 Voor update product - controles Na update product - logging Update voor product: Ipoh Coffee: RL = 24 Voor update product - controles Na update product - logging Update voor product: Rhönbräu Klosterbier: RL = 24 Voor update product - controles Na update product - logging
try
{
NorthwindDataContext db = new NorthwindDataContext();
var products = from p in db.Products
where p.Category.CategoryName == "Beverages"
where p.ReorderLevel == 24
select p;
foreach (Product p in products)
{
p.ReorderLevel = 25;
lblError.Text = "";
}
gvUpdate.DataSource = db.GetChangeSet().Updates;
gvUpdate.DataBind();
db.SubmitChanges();
BindProductsGrid();
}
catch (Exception ex)
{
lblError.Text = ex.Message;
}
Zorg er natuurlijk voor dat de variabele products in jouw situatie effectief producten bevat door de query desnoods aan te passen.
| Meer tutorials: |
| leer ook: | html | | xhtml | | css | | asp | | asp.net | | c# | | ado.net | | linq | | ajax | | java | | javascript |