2012-10-03 18 views
8

PostgreSQLデータベースでO/RマッパーとしてEntity-Framework 5.0を使用したいと思います。私はすでに多くのHowTosを読んでいますが、私はまだまだ立ち往生しています。たぶん私はEFの背後に全体のアイデアを得ることはできません。私が欲しいものEntity-Framework 5.0 with PostgreSQL

  • は、私は自分でコードを書きたいです。次に、いくつかの属性をプロパティとクラスに入れて、EFにオブジェクトのマッピング方法を伝えます(NHibernateと同様)。
  • モデルからデータベースを生成したくない - 既存のモデルを使用したいだけです。

例モデル:

[Table("device")] 
public class Device 
{ 
    [Key] 
    public int Id { get; set; } 

    [StringLength(255)] 
    public string Identifier { get; set; } 
} 

[Table("customer")] 
public class Customer 
{ 
    public Customer() 
    { 
     this.Devices = new List<Device>(); 
    } 

    [Key] 
    public int Id { get; set; } 

    [StringLength(255)] 
    public string Name { get; set; } 

    // attribute required? 
    public List<Device> Devices { get; set; } 
} 

私がやった:

  • はDatabaseContextクラス
  • 追加DbProviderFactoriesとのconnectionStrings番目に作成
  • 上記のコードを書きました電子のapp.configを
  • はEdmGen.exeツールでSSDL、MSL、CSDLファイルを生成し、(これらのファイルはbinフォルダにも利用可能です)プロジェクトに

DatabaseContextそれらをコピー:

public class DatabaseContext : DbContext 
{ 
    static DatabaseContext() 
    { 
     Database.SetInitializer<DatabaseContext>(null); 
    } 

    public DatabaseContext() 
     : base("PostgreSQL") 
    { 

    } 

    public DbSet<Customer> Customers { get; set; } 
    public DbSet<Device> Devices { get; set; } 
} 

のapp.config:

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <configSections> 
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> 
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> 
    </configSections> 
    <startup> 
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> 
    </startup> 

    <system.data> 
    <DbProviderFactories> 
     <remove invariant="Npgsql" /> 
     <add name="Npgsql Data Provider" invariant="Npgsql" support="FF" description=".Net Framework Data Provider for Postgresql Server" type="Npgsql.NpgsqlFactory, Npgsql, Version=2.0.12.0, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7" /> 
    </DbProviderFactories> 
    </system.data> 

    <connectionStrings> 
    <add name="PostGreSQL" 
     providerName="System.Data.EntityClient" 
     connectionString="metadata=.;provider=Npgsql;provider connection string=&quot;Server=asdf;Port=5432;User Id=asdf;Password=asdf;Database=asdf;enlist=true&quot;" /> 
    </connectionStrings> 

</configuration> 

テスト:

using (DatabaseContext context = new DatabaseContext()) 
{ 
    if (context.Database.Exists()) 
    { 
     Console.WriteLine("yep"); 
    } 
    else 
    { 
     Console.WriteLine("nope"); 
    } 

    foreach (Customer c in context.Customers) 
    { 
     Console.WriteLine("Name={0}", c.Name); 
    } 
} 

Console.ReadLine(); 

出力&エラー:

"うん" ..データベースが存在することを意味します。 しかしcontext.Customersプロパティにアクセスするとき、私は次の例外を取得:

The entity type Customer is not part of the model for the current context. 

をスタックトレース:

at System.Data.Entity.Internal.InternalContext.UpdateEntitySetMappingsForType(Type entityType) 
    at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) 
    at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize() 
    at System.Data.Entity.Internal.Linq.InternalSet`1.GetEnumerator() 
    at System.Data.Entity.Infrastructure.DbQuery`1.System.Collections.Generic.IEnumerable<TResult>.GetEnumerator() 
    at EF5.Program.Main(String[] args) in c:\Users\tba\Documents\Visual Studio 2012\Projects\EF5\EF5\Program.cs:line 26 
    at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
    at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
    at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
    at System.Threading.ThreadHelper.ThreadStart() 

私は理解していないもの:

  • 何ですかDataAnnoationsが利用可能な場合は、ssdl、msl、csdlファイルが適していますか?
  • Customerクラスが現在のコンテキストのモデルの一部でないのはなぜですか?

また、EdmGen.exeツールを使用すると、ObjectContextおよびエンティティクラスを含むObjectLayer.csファイルも生成されます。その問題は、エンティティクラスがEntityObjectから派生していることです。エンティティクラスをビジネスクラスとして使用したい場合、クラスは他のクラスから派生することができないため、これは深刻な問題です。

さらに、私はObjectContextを生成する理由を理解していません。私が見つけたすべてのHowToはDbContextクラスを使用しています。

EdmGenツールによって生成エンティティCustomerクラス:

/// <summary> 
/// No Metadata Documentation available. 
/// </summary> 
[EdmEntityTypeAttribute(NamespaceName="EF5", Name="Customer")] 
[Serializable()] 
[DataContractAttribute(IsReference=true)] 
public partial class Customer : EntityObject 

私は混乱して:-)

編集:私はObjectLayer.csを使用していない

  • ファイル!また、私が上に述べた継承の問題のために、私はそれを使いたくありません。部分Customerクラスは、EdmGenツールが生成する内容を示すための単なる例です。
  • 私は、私は次のエラーを取得するCSDL、MSLとSSDLファイルを削除する場合:

    At least one SSDL artifact is required for creating StoreItemCollection. 
    
  • 私は、私は次のエラーを取得するのapp.configでConnectionStringプロパティからメタデータのキーワードを削除する場合:

    Some required information is missing from the connection string. The 'metadata' keyword is always required. 
    



ソリューション:

私は最終的にどのように動作するかを考え出しました。 app.configのconnectionStringが間違っています。正しい接続文字列:

<connectionStrings> 
    <add name="PostgreSQL" 
     connectionString="Server=asdf;Port=5432;User Id=asdf;Password=asdf;Database=asdf;" 
     providerName="Npgsql" /> 
</connectionStrings> 

メタデータ、プロバイダ、プロバイダ接続文字列プロパティをconnectionStringから削除しました。 Briceと同様に、メタデータファイルは不要なので、削除しました。

また、DeviceクラスとCustomerクラスのTable-Attributeはスキーマを指定する必要があります。このように:

[Table("customer", Schema="public")] 
public class Customer 
+1

モデルファーストワークフローとコードファーストワークフローを混在させているようです。 EFの使用の詳細については、[http://msdn.com/data/ef](http://msdn.microsoft.com/en-us/data/ee712907)の[Getting Started]ビデオをご覧ください。 – bricelam

+1

簡単な例が素晴らしいでしょう。 PostgreSQLデータベースでEF5を使用するプロジェクト。デザイナーなしで、コード(帰属コード)。 – bakunin

+2

完了:[PostgreSQLのエンティティフレームワーク](http://brice-lambson.blogspot.com/2012/10/entity-framework-on-postgresql.html) – bricelam

答えて

4

ssdl、msl、csdlファイルを生成しないでください。これらのファイルは、デザイナを使用する場合にのみ必要です。これらのファイルと生成されたObjectLayer.csを削除します。

また、EntityClient接続文字列を使用しないでください。単純に以下のように接続文字列を更新します。

<connectionStrings> 
    <add name="PostGreSQL" 
     providerName="Npgsql" 
     connectionString="Server=asdf;Port=5432;User Id=asdf;Password=asdf;Database=asdf;enlist=true" /> 
</connectionStrings> 
+0

私の編集した記事を参照してください。私はObjectLayer.csファイルを使用しません。 – bakunin

+0

私の答えが更新されました。あなたの問題は単に接続文字列であるように見えます。 – bricelam

+0

Doh、あなたはそれが働いているように見えます。 :) よくやった – bricelam