İlk Entity Framework konsepti kullanarak yeni bir veritabanı oluşturmaya çalışıyorum. Ancak kodu çalıştırırken, kod düzgün çalışmıyor olsa da (DropCreateDatabaseIfModelChanges
ayarını kullanarak) veritabanı oluşturulmaz. Veritabanından bir şey almaya çalıştığımda aşağıdaki özel durumu görüyorum.Entity Framework 5 code-first veri tabanı oluşturmuyor
Benim projem, bir jenerik servis ve depo inşaatı ile ayrı DataAccess
katmanı kullanılarak kurulduğundan. Böylece bütün varlıklarım, depolarım ve ayrıca veritabanı bağlamları çözüm içinde ayrı bir projede.
Benim global.asax
dosya aşağıdaki kod parçasını içerir.
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyContext>());
Bu, yoksa yeni bir veritabanını başlatmalı, doğru mu?
Veritabanı bağlam sınıfım şunun gibi görünüyor;
namespace Website.DAL.Model
{
public class MyContext : DbContext
{
public IDbSet<Project> Projects { get; set; }
public IDbSet<Portfolio> Portfolios { get; set; }
/// <summary>
/// The constructor, we provide the connectionstring to be used to it's base class.
/// </summary>
public MyContext()
: base("MyConnectionString")
{
}
static MyContext()
{
try
{
Database.SetInitializer<MyContext>(new DropCreateDatabaseIfModelChanges<MyContext>());
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// This method prevents the plurarization of table names
/// </summary>
/// <param name="modelBuilder"></param>
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<System.Data.Entity.ModelConfiguration.Conventions.PluralizingTableNameConvention>();
}
}
}
Bu sınıfa, internetteki çeşitli eğitici ve makaleleri takip ederek oluşturdum. Her şey benim için yeni, ama görebildiğim kadarıyla her şey doğru görünüyor. Yani şimdi kullanıyorum iki varlık. 'Proje' ve 'Portföy' olarak adlandırılıyorlar. Bu gibi görünüyorlar;
public class Portfolio
{
[Key]
public Guid Id { get; set; }
public String Name { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public bool IsPublished { get; set; }
public virtual ICollection<Project> Projects { get; set; }
}
Ve
public class Project
{
[Key]
public Guid Id { get; set; }
public DateTime StartDate { get; set; }
public DateTime? EndDate { get; set; }
public bool IsPublished { get; set; }
public String Title { get; set; }
}
Ben harici bir sunucuda çalışan kullanıyorum veritabanı
, ben kullanıyorum barındırma sağlayıcı ile geldi. Bir SQL Server veritabanım var ve çalışıyor ve veritabanına bağlantı dizesi web sitesi projesininweb.config
. Veritabanını kaldırmayı denedim ve kodun yeniden oluşturmasına izin verdim, maalesef çalışmadı. Burada bariz bir şey eksik miyim? Ya da sunucu için veritabanı oluşturma erişim hakları gibi basit bir şey olabilir mi?
Not: SQL kodu oluşturmak için Database-Update -Script
komutunu çalıştırdığımda, tüm tabloları oluşturmak için doğru SQL deyimlerinin oluşturulduğu anlaşılıyor.
UPDATE 1: Pekala, bazı yorumlar sayesinde biraz daha ileri gittim. Bazı değişiklikleri zorlamak için varlıklarıma iki özellik ekledim ve bunun gibi özel bir başlatıcı da oluşturdum;
public class ForceDeleteInitializer : IDatabaseInitializer<MyContext>
{
private readonly IDatabaseInitializer<MyContext> _initializer = new DropCreateDatabaseIfModelChanges<MyContext>();
public ForceDeleteInitializer()
{
//_initializer = new ForceDeleteInitializer();
}
public void InitializeDatabase(MyContext context)
{
//This command is added to prevent open connections. See http://stackoverflow.com/questions/5288996/database-in-use-error-with-entity-framework-4-code-first
context.Database.ExecuteSqlCommand("ALTER DATABASE borloOntwikkel SET SINGLE_USER WITH ROLLBACK IMMEDIATE");
_initializer.InitializeDatabase(context);
}
}
Ben de bağlamın kurucusundan başlatıcı kaldırdık, bu nedenle bu ortalama i kod satırını kaldırmak ettik;
Database.SetInitializer<MyContext>(new DropCreateDatabaseIfModelChanges<MyContext>());
Bundan sonra, bu üç satırı Global'ime ekledim.asax dosyası;
Database.SetInitializer(new ForceDeleteInitializer());
MyContext c = new MyContext();
c.Database.Initialize(true);
Hata ayıklaması yaparken şimdi bu özel durumu alıyorum;
Bu şu bilgileri veriyor:
- InnerException diyor ki: sağlayıcı InnerException bir ProviderManifestToken
- InnerException dönmedi diyor ki: "Bu işlem için bir bağlantı için asıl bağlantı açıldı ve başvurular bağlantıdan kaldırılmış olduğundan, bağlantı 'master' veritabanına genişliğinde bir bağlantı olamaz.
muhtemelen bu konuda ne yapılabilir .. veritabanı, bu yüzden büyük olasılıkla silinmiş erişilemez bu eylemin ardından olmayan bir açık bağlantı"
veriniz? Büyük olasılıkla ana veritabanına erişemem çünkü hosting sunucum bana uygun erişim hakkını vermiyor. Ayrıntılı soru için
Kod ve yapılandırma tamam görünüyor, muhtemelen barındırma durumuna takıldınız. EF, Db'nizi özel bir yardımcı tabloyla oluşturmak ister (1 veya 2 sağlama). Belki bunu yerel bir Db'den betimleyebilir ve barındırılan Db'ye taşıyabilirsiniz? –
Kodunuzu çalıştıran kullanıcı hesabı, veritabanlarını bırakmak ve oluşturmak için gerekli izinlere sahip mi? – jlew
@Henk, sadece oluşturulan SQL komut dosyasını çalıştırmayı denedim. Bir kayıt için benim için bir __MigrationHistory tablosu oluşturdu. Ayrıca 'this.Database.Initialize (true)' satırını ekleyerek içeriğimin yapıcısını değiştirdim. Bu bana bir hata vermedi, ancak herhangi bir tablo oluşturmadı. Daha sonra kayıtları MigrationHistory tablosundan düşürdüm ve yine aynı hatayı aldım. Bu yüzden şimdi yerel bir veritabanında çalıştırmayı ve ne olacağını görmeyi deneyeceğim. – Rob