SQL Anywhere .NET データプロバイダーでは Entity Framework 4.2 がサポートされています。Entity Framework は Microsoft から別個のパッケージとして入手できます。Entity Framework 4.2 を使用するには、Microsoft の NuGet Package Manager を使用して Visual Studio に追加する必要があります。
Entity Framework の新機能の 1 つに Code First があります。この機能では異なる開発ワークフローが可能です。C# または VB.NET のクラスを記述するだけでデータモデルが定義され、データベースオブジェクトにマッピングされます。デザイナを開く必要も XML マッピングファイルを定義する必要もありません。または、データの注釈や Fluent API を使用して追加の設定を実行することもできます。モデルを使用して、データベーススキーマを生成したり既存のデータベースにマッピングしたりできます。
次の例は、このモデルを使用して新しいデータベースオブジェクトを作成します。
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Linq; using iAnywhere.Data.SQLAnywhere; namespace CodeFirstExample { [Table( "EdmCategories", Schema = "DBA" )] public class Category { public string CategoryID { get; set; } [MaxLength( 64 )] public string Name { get; set; } public virtual ICollection<Product> Products { get; set; } } [Table( "EdmProducts", Schema = "DBA" )] public class Product { public int ProductId { get; set; } [MaxLength( 64 )] public string Name { get; set; } public string CategoryID { get; set; } public virtual Category Category { get; set; } } [Table( "EdmSuppliers", Schema = "DBA" )] public class Supplier { [Key] public string SupplierCode { get; set; } [MaxLength( 64 )] public string Name { get; set; } } public class Context : DbContext { public Context() : base() { } public Context( string connStr ) : base( connStr ) { } public DbSet<Category> Categories { get; set; } public DbSet<Product> Products { get; set; } public DbSet<Supplier> Suppliers { get; set; } protected override void OnModelCreating( DbModelBuilder modelBuilder ) { modelBuilder.Entity<Supplier>().Property( s => s.Name ).IsRequired(); } } class Program { static void Main( string[] args ) { Database.DefaultConnectionFactory = new SAConnectionFactory(); Database.SetInitializer<Context>( new DropCreateDatabaseAlways<Context>() ); using ( var db = new Context( "DSN=SQL Anywhere 12 Demo" ) ) { var query = db.Products.ToList(); } } } } |
この例を構築して実行するには、次のアセンブリ参照を追加する必要があります。
EntityFramework iAnywhere.Data.SQLAnywhere.v4.0 System.ComponentModel.DataAnnotations System.Data.Entity |
次の例は、既存のデータベースにマッピングします。
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Linq; using iAnywhere.Data.SQLAnywhere; namespace CodeFirstExample { [Table( "Customers", Schema = "GROUPO" )] public class Customer { [Key()] public int ID { get; set; } public string SurName { get; set; } public string GivenName { get; set; } public string Street { get; set; } public string City { get; set; } public string State { get; set; } public string Country { get; set; } public string PostalCode { get; set; } public string Phone { get; set; } public string CompanyName { get; set; } public virtual ICollection<Contact> Contacts { get; set; } } [Table( "Contacts", Schema = "GROUPO" )] public class Contact { [Key()] public int ID { get; set; } public string SurName { get; set; } public string GivenName { get; set; } public string Title { get; set; } public string Street { get; set; } public string City { get; set; } public string State { get; set; } public string Country { get; set; } public string PostalCode { get; set; } public string Phone { get; set; } public string Fax { get; set; } [ForeignKey( "Customer" )] public int CustomerID { get; set; } public virtual Customer Customer { get; set; } } public class Context : DbContext { public Context() : base() { } public Context( string connStr ) : base( connStr ) { } public DbSet<Contact> Contacts { get; set; } public DbSet<Customer> Customers { get; set; } } class Program { static void Main( string[] args ) { Database.DefaultConnectionFactory = new SAConnectionFactory(); Database.SetInitializer<Context>( null ); using ( var db = new Context( "DSN=SQL Anywhere 12 Demo" ) ) { foreach ( var customer in db.Customers.ToList() ) { Console.WriteLine( "Customer - " + string.Format( "{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}", customer.ID, customer.SurName, customer.GivenName, customer.Street, customer.City, customer.State, customer.Country, customer.PostalCode, customer.Phone, customer.CompanyName ) ); foreach ( var contact in customer.Contacts ) { Console.WriteLine( " Contact - " + string.Format( "{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8}, {9}, {10}", contact.ID, contact.SurName, contact.GivenName, contact.Title, contact.Street, contact.City, contact.State, contact.Country, contact.PostalCode, contact.Phone, contact.Fax ) ); } } } } } } |
Microsoft SQL Server SqlClient プロバイダーと SQL Anywhere .NET プロバイダーとでは、実装の詳細部分でいくつかの違いがあり、それらを理解しておく必要があります。
新しいクラス SAConnectionFactory (IDbConnectionFactory を実装) が追加されています。次のように、Database.DefaultConnectionFactory に SAConnectionFactory のインスタンスを設定してから、データモデルを作成します。
Database.DefaultConnectionFactory = new SAConnectionFactory(); |
Entity Framework の Code First では、原則として規則によるコーディングを行います。Entity Framework では、規則をコーディングすることによってデータモデルが推測されます。また、自動的な処理が多数行われます。場合によっては、開発者が Entity Framework のすべての規則を把握できないこともあります。しかし、SQL Anywhere で意味を持たないコード規則もあります。SQL Server と SQL Anywhere の間には大きな違いがあります。SQL Server のインスタンスはすべて複数のデータベースを保持しますが、SQL Anywhere のデータベースはすべて単一のファイルです。
ユーザーがパラメーターのないコンストラクターを使用してユーザー定義の DbContext を作成した場合、SqlClient では統合セキュリティを使用してローカルマシンの SQL Server Express に接続します。SQL Anywhere プロバイダーでは、ユーザーがすでにログインマッピングを作成している場合、統合ログインを使用してデフォルトのサーバーに接続します。
SqlClient では、EF から DbDeleteDatabase または DbCreateDatabase を呼び出したときに、既存のデータベースを削除して新しいデータベースを作成します (SQL Server Express Edition のみ)。SQL Anywhere プロバイダーではデータベースの削除や作成をすることは決してなく、データベースオブジェクト (テーブル、関係、制約など) を作成または削除します。ユーザーは最初にデータベースを作成する必要があります。
IDbConnectionFactory.CreateConnection メソッドでは、文字列パラメーター "nameOrConnectionString" がデータベース名 (SQL Server では初期カタログ) または接続文字列として扱われます。ユーザーが DbContext の接続文字列を指定しない場合、SqlClient では、ユーザー定義の DbContext クラスのネームスペースを初期カタログとして使用し、ローカルマシンの SQL Express サーバーに自動的に接続します。SQL Anywhere では、このパラメーターに接続文字列のみ含めることができます。データベース名は無視され、代わりに統合ログインが使用されます。
SQL Server SqlClient API では、データ注釈属性 TimeStamp を持つカラムが、SQL Server のデータ型 timestamp/rowversion にマッピングされます。SQL Server の timestamp/rowversion については開発者のあいだで誤解されている面があります。SQL Server の timestamp/rowversion データ型は、SQL Anywhere や他のほとんどのデータベースベンダーとは異なります。
SQL Server の timestamp/rowversion はバイナリ (8) です。日付と時刻の組み合わせ値はサポートされていません。SQL Anywhere でサポートされている timestamp というデータ型は、SQL Server の datetime データ型と同等です。
SQL Server の timestamp/rowversion 値はユニークであることが保証されています。SQL Anywhere の timestamp 値はユニークではありません。
SQL Server の timestamp/rowversion 値は、ローが更新されるたびに変更されます。
TimeStamp データ注釈属性は SQL Anywhere プロバイダーではサポートされていません。
Entity Framework 4.1 のデフォルトでは、スキーマ名または所有者名が常に dbo に設定されます。これは SQL Server のデフォルトのスキーマです。ただし、dbo は SQL Anywhere では適切ではありません。SQL Anywhere では、データ注釈か Fluent API のどちらかを使用して、テーブル名を持つスキーマ名 (GROUPO など) を指定する必要があります。次に例を示します。
namespace CodeFirstTest { public class Customer { [Key()] public int ID { get; set; } public string SurName { get; set; } public string GivenName { get; set; } public string Street { get; set; } public string City { get; set; } public string State { get; set; } public string Country { get; set; } public string PostalCode { get; set; } public string Phone { get; set; } public string CompanyName { get; set; } public virtual ICollection<Contact> Contacts { get; set; } } public class Contact { [Key()] public int ID { get; set; } public string SurName { get; set; } public string GivenName { get; set; } public string Title { get; set; } public string Street { get; set; } public string City { get; set; } public string State { get; set; } public string Country { get; set; } public string PostalCode { get; set; } public string Phone { get; set; } public string Fax { get; set; } [ForeignKey( "Customer" )] public int CustomerID { get; set; } public virtual Customer Customer { get; set; } } [Table( "Departments", Schema = "GROUPO" )] public class Department { [Key()] public int DepartmentID { get; set; } public string DepartmentName { get; set; } public int DepartmentHeadID { get; set; } } public class Context : DbContext { public Context() : base() { } public Context( string connStr ) : base( connStr ) { } public DbSet<Contact> Contacts { get; set; } public DbSet<Customer> Customers { get; set; } public DbSet<Department> Departments { get; set; } protected override void OnModelCreating( DbModelBuilder modelBuilder ) { modelBuilder.Entity<Contact>().ToTable( "Contacts", "GROUPO" ); modelBuilder.Entity<Customer>().ToTable( "Customers", "GROUPO" ); } } } |
![]() |
DocCommentXchange で意見交換できます
|
Copyright © 2012, iAnywhere Solutions, Inc. - SQL Anywhere 12.0.1 |