2017-04-25 59 views
14

App.config'i değiştiremediğim bir uygulama için EF6.1 ve SQLite kullanacak bir eklenti yapmaya çalışıyorum, böylece tüm yapılandırma ve bağlantı dizenin kod olarak ayarlanması gerekir.EF6, SQLite, App.confg olmadan çalışmayacak

public class CollectionDbConfiguration : DbConfiguration 
{ 
    public CollectionDbConfiguration() 
    { 
     SetProviderServices("System.Data.SQLite"(DbProviderServices)SQLiteProviderFactory.Instance.GetService(typeof(DbProviderServices))); 
     SetProviderFactory("System.Data.SQLite.EF6", SQLiteProviderFactory.Instance); 
     SetProviderFactory("System.Data.SQLite", SQLiteFactory.Instance);     
    } 
} 

ben bağlam ilk kez ve tüm oluşturulmadan önce bu darbe aldığında doğrulamıştır:

ben böyle bir yapılandırma sınıf var Şimdi umut verici Problems using Entity Framework 6 and SQLite

baktı bu cevabı bulundu bu dönüş değerleri.

Benim bağlam bu

public class MyContext : DbContext 
{ 
    public MyContext(string connectionString) 
    : base(connectionString) { } 

    public DbSet<MyEntity> MyEntities { get; set; }  
} 

benziyor Ve ben böyle çağırarak bazı kodlar vardır:

var context = new MyContext("Data Source = mytest.db; Version = 3;"); 
var entities = context.MyEntities.ToList(); 

denemek ve bağlam gibi görünüyor kod çalıştırmasına bağlantı dizesini üstleniyor SQL Server için bana verdiği gibi:

Anahtar kelime desteklenmiyor: 'version'.

Eğer kaldırırsam, bağlanamayacağı ve SQL Server veritabanına bağlanmaya çalıştığı açıkça bir hata alıyorum.

public MyContext(DbConnection connection) 
    : base(connection, contextOwnsConnection: true) 
{ } 

Ve bununla çağırmak:

Bir yapıcı ekleyerek SQLite bağlantılı olarak geçen çalıştı

var context = new MyContext(new SQLiteConnection("Data Source = mytest.db; Version = 3;")); 
var entities = context.MyEntities.ToList(); 

Ama sonra hatayı alıyorum:

belirlenemedi 'System.Data.SQLite.SQLiteConnection' türünün bağlantısı için DbProviderFactory türü. ADO.NET sağlayıcısının uygulama yapılandırmasında yüklü veya kayıtlı olduğundan emin olun.

Bu yüzden bir fabrika çözümleyicinizi yapan ve bu

public class FactoryResolver : IDbProviderFactoryResolver 
{ 
    public DbProviderFactory ResolveProviderFactory(DbConnection connection) 
    { 
     if (connection.GetType() == typeof(SQLiteConnection)) 
     { 
      return SQLiteFactory.Instance; 
     } 

     if (connection.GetType() == typeof(EntityConnection)) 
     { 
      return SQLiteProviderFactory.Instance; 
     } 

     return null; 
    } 
} 

kayıtlı Ve ekledi:

SetProviderFactoryResolver(new FactoryResolver()); 

ama şimdi bu olsun:

Yok varlık Framework sağlayıcı ADO.NET bulundu 'System.Data.SQLite.EF6' değişmez ismi olan sağlayıcı. Sağlayıcının, uygulama yapılandırma dosyasının 'entityFramework' bölümüne kayıtlı olduğundan emin olun. Daha fazla bilgi için bkz. http://go.microsoft.com/fwlink/?LinkId=260882.

Şu an iki gün boyunca pancar yapıyorum ve fikirlerim tükendi.

public class SQLiteProviderInvariantName : IProviderInvariantName 
{ 
    public static readonly SQLiteProviderInvariantName Instance = new SQLiteProviderInvariantName(); 
    private SQLiteProviderInvariantName() { } 
    public const string ProviderName = "System.Data.SQLite.EF6"; 
    public string Name { get { return ProviderName; } } 
} 

class SQLiteDbDependencyResolver : IDbDependencyResolver 
{ 
    public object GetService(Type type, object key) 
    { 
     if (type == typeof(IProviderInvariantName)) return SQLiteProviderInvariantName.Instance; 
     if (type == typeof(DbProviderFactory)) return SQLiteProviderFactory.Instance; 
     return SQLiteProviderFactory.Instance.GetService(type); 
    } 

    public IEnumerable<object> GetServices(Type type, object key) 
    { 
     var service = GetService(type, key); 
     if (service != null) yield return service; 
    } 
} 

class SQLiteDbConfiguration : DbConfiguration 
{ 
    public SQLiteDbConfiguration() 
    { 
     AddDependencyResolver(new SQLiteDbDependencyResolver()); 
    } 
} 

Şimdi bu çalışması gerekir:

var context = new MyContext("Data Source = mytest.db; Version = 3;"); 
var entities = context.MyEntities.ToList(); 

Güncelleme: NET4 için

cevap

13

bağlantı dizesi çalışma ile yapıcı hale getirmek için gereken minimum özel IProviderInvariantName, IDbDependencyResolver ve DbConfiguration olduğunu. 0 ayrıca özel bir IDbProviderFactoryResolver:

'ye de ihtiyacınız olacaktır

ve SQLiteDbDependencyResolver.GetService yöntem uygulanmasına

if (type == typeof(IDbProviderFactoryResolver)) return SQLiteDbProviderFactoryResolver.Instance; 

ekleyin.

+0

Bunu denedim ama şimdi hata iletisini alıyorum: 'System.Data.SQLite.SQLiteConnection' türünün bağlantısı için DbProviderFactory türünü belirleyemedi. ADO.NET sağlayıcısının uygulama yapılandırmasında yüklü veya kayıtlı olduğundan emin olun. – Mant101

+0

Bu garip çünkü konuyu tam olarak açıkladığınız şekilde kopyalayabildim ve daha sonra da düzeltildi. Projenin içinde başka bir "DbConfiguration" sınıfı bulunmadığından (örneğin, yayınlanan kodda kullandığınız gibi) ve çözümleyicilerin - yanıtın yalnızca sınıfları olmadığından emin olun. Ve kurucuyu bağlantı dizgisiyle, bağlantıyla değil de kullanırsınız. Gördüğünüz gibi, yukarıdaki 'IDbDependencyResolver' brute force' DbProviderFactory' düzeltir, bu yüzden böyle bir hata almamalı. –

+0

Tam bir repro projesi sağlayabiliyorsanız, buna bir göz atabilirim, ama çözümün bu olduğuna inanıyorum çünkü SQLite veritabanı ile App.config'den SQLite ile ilgili bağlantıları açık bir şekilde yorumlayabildiğim için çalışabildim ve localdb varsayılanını korumak, SqlServer ve MySQL –