zurück zum Artikel

.NET-LINQ und Microsofts Access-Datenbanken

Dr. Holger Schwichtenberg

Wie man mit Language Integrated Query (LINQ) in C# oder Visual Basic .NET auf Microsofts Access-Datenbanken zugreifen kann.

Auf der SQL Server und .NET-Konferenz (SNEK) [1] in Nürnberg wurde ich gefragt, ob man mit dem ADO.NET Entity Framework [2]/LINQ-to-Entities [3] auf Microsofts Access-Datenbanken zugreifen kann. Microsoft liefert einen solchen Treiber nicht. Auch ist mir kein Drittanbieter bekannt, der einen Entity-Framework-Treiber für Access liefert.

Es gibt aber im Rahmen des LINQ IQueryable Toolkit [4] einen direkten LINQ-Provider für Access (IQToolkit.Data.Access.dll). Bei diesem Provider, den ich selbst schon eingesetzt habe, kann man mit LINQ [5](einschließlich der zugehörigen Lambda-Syntax) Daten lesen und über eine API, die der von LINQ-to-SQL [6]und ADO.NET Entity Framework ähnlich ist, auch speichern. Beispiel:

var provider = DbEntityProvider.From(@"c:\data\Northwind.accdb", 
"Test.Northwind");
var ns = new NorthwindSession(provider);
cust = ns.Customers.Single(c => c.CustomerID == "XX1");
cust.ContactName = "Contact Modified";
ns.SubmitChanges();

Die Klassen für die Access-Tabellen muss man allerdings selbst anlegen. (Oder sich selbst einen Generator schreiben. Ich habe mir dazu ein T4-Template [7] gebaut). Einen Designer für Visual Studio gibt es nicht. Es reichen POCO-Klassen [8] wie diese:

namespace Test
{
public class Customer
{
public string CustomerID;
public string ContactName;
public string CompanyName;
public string Phone;
public string City;
public string Country;
public IList<Order> Orders;
}
...
}

Alternativ kann man das Mapping auch durch Annotationen mit .NET-Attributen steuern:

  [Table]
[Column(Member = "CustomerId", IsPrimaryKey = true)]
[Column(Member = "ContactName")]
[Column(Member = "CompanyName")]
[Column(Member = "Phone")]
[Column(Member = "City", DbType="NVARCHAR(20)")]
[Column(Member = "Country")]
[Association(Member = "Orders", KeyMembers = "CustomerID",
RelatedEntityID = "Orders", RelatedKeyMembers = "CustomerID")]
public override IEntityTable<Customer> Customers
{
get { return base.Customers; }
}

Andere Benutzer im Internet berichten von folgenden Lösungen zum Thema LINQ und Access, die ich aber nicht ausprobiert habe:

( [11])


URL dieses Artikels:
https://www.heise.de/-1479798

Links in diesem Artikel:
[1] http://www.donkarl.com/SNEK/
[2] http://www.it-visions.de/Lex/4365.aspx
[3] http://www.it-visions.de/Lex/5347.aspx
[4] http://iqtoolkit.codeplex.com/
[5] http://www.it-visions.de/Lex/3777.aspx
[6] http://www.it-visions.de/Lex/4987.aspx
[7] http://www.it-visions.de/Lex/5743.aspx
[8] http://www.it-visions.de/Lex/4914.aspx
[9] http://stackoverflow.com/questions/295772/query-microsoft-access-mdb-database-using-linq-and-c-sharp
[10] http://www.alinq.org/
[11] mailto:hs@ix.de