Tôi đang cố tạo một cơ sở dữ liệu mới bằng cách sử dụng khái niệm đầu tiên của khung Entity Framework. Tuy nhiên khi chạy mã cơ sở dữ liệu không được tạo ra (sử dụng thiết lập DropCreateDatabaseIfModelChanges
), mặc dù mã đang chạy tốt. Tôi thấy ngoại lệ sau khi tôi cố gắng lấy thứ gì đó từ cơ sở dữ liệu.Entity Framework 5 code-first không tạo cơ sở dữ liệu
Dự án của tôi được thiết lập sử dụng một lớp riêng biệt DataAccess
với một dịch vụ chung và xây dựng kho. Vì vậy, tất cả các thực thể của tôi, kho lưu trữ và bối cảnh cơ sở dữ liệu cũng nằm trong một dự án riêng biệt trong giải pháp.
Tệp global.asax
của tôi chứa đoạn mã sau.
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MyContext>());
Điều này sẽ khởi tạo cơ sở dữ liệu mới nếu không có ở đó, phải không?
Lớp ngữ cảnh cơ sở dữ liệu của tôi trông như thế này;
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>();
}
}
}
Tôi đã tạo lớp này theo một số hướng dẫn và bài viết trên internet. Đó là tất cả mới với tôi, nhưng theo như tôi có thể thấy tất cả mọi thứ có vẻ chính xác cho đến nay. Vì vậy, bây giờ hai thực thể tôi đang sử dụng. Chúng được gọi là 'Project' và 'Portfolio'. Họ trông như thế này;
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; }
}
Và
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; }
}
Cơ sở dữ liệu Tôi đang sử dụng đang chạy trên một máy chủ bên ngoài, nó đi kèm với các nhà cung cấp hosting Tôi đang sử dụng. Tôi đã có một cơ sở dữ liệu SQL Server và chạy và chuỗi kết nối đến cơ sở dữ liệu nằm trong web.config
của dự án trang web. Tôi đã thử loại bỏ cơ sở dữ liệu và để cho mã tái tạo nó, mà tiếc là không hoạt động. Tôi có thiếu thứ gì đó hiển nhiên ở đây không? Hoặc nó có thể là một điều đơn giản như quyền truy cập vào máy chủ để tạo cơ sở dữ liệu?
Lưu ý: Khi tôi chạy lệnh Database-Update -Script
để tạo mã SQL, có vẻ như các câu lệnh SQL đúng để tạo tất cả các bảng được tạo.
CẬP NHẬT 1: Được rồi, nhờ một số nhận xét tôi đã tiến xa hơn một chút. Tôi đã thêm hai thuộc tính cho các thực thể của mình để bắt buộc một số thay đổi và tôi cũng đã tạo một trình khởi tạo tùy chỉnh như thế này;
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);
}
}
Tôi cũng đã xóa trình khởi tạo khỏi hàm tạo của ngữ cảnh, vì vậy điều này có nghĩa là tôi đã xóa dòng mã này;
Database.SetInitializer<MyContext>(new DropCreateDatabaseIfModelChanges<MyContext>());
Sau đó tôi đã thêm ba dòng này vào toàn cầu của mình.tập tin asax;
Database.SetInitializer(new ForceDeleteInitializer());
MyContext c = new MyContext();
c.Database.Initialize(true);
Khi gỡ lỗi, tôi hiện đang nhận ngoại lệ này;
này mang lại cho tôi những thông tin sau:
- InnerException cho biết: Các nhà cung cấp không trở về một ProviderManifestToken
- InnerException trong InnerException cho biết: "Đối với hoạt động này một kết nối đến Kết nối không thể là đã tạo chiều rộng cơ sở dữ liệu 'master' vì kết nối ban đầu là được mở và các tham chiếu đã bị xóa khỏi kết nối. Vui lòng cung cấp một kết nối không mở"
Sau những hành động cơ sở dữ liệu là không thể tiếp cận, vì vậy rất có thể xóa ..
gì có thể có thể được thực hiện về vấn đề này? Nó rất có thể là tôi không thể truy cập cơ sở dữ liệu tổng thể vì hostingprovider của tôi sẽ không cho tôi quyền truy cập thích hợp.
Mã và cấu hình trông OK, có thể bạn đang gặp phải tình huống lưu trữ. EF muốn tạo Db của bạn với một bảng trợ giúp đặc biệt trong đó (1 hoặc 2 băm). Có lẽ bạn có thể kịch bản nó từ một Db địa phương và di chuyển nó vào Db lưu trữ? –
Tài khoản người dùng đang chạy mã của bạn có các quyền cần thiết để thả và tạo cơ sở dữ liệu không? – jlew
@Henk, tôi vừa thử chạy tập lệnh SQL đã tạo. Nó tạo ra một bảng __MigrationHistory cho tôi với một bản ghi. Tôi cũng đã sửa đổi hàm tạo của ngữ cảnh của tôi bằng cách thêm dòng 'this.Database.Initialize (true)'. Điều này đã không cho tôi một lỗi, nhưng không tạo ra bất kỳ bảng nào. Sau đó tôi đã xóa bản ghi từ bảng MigrationHistory và tôi lại gặp lỗi tương tự. Vì vậy, tôi sẽ thử chạy nó trên một cơ sở dữ liệu địa phương ngay bây giờ và xem những gì sẽ xảy ra. – Rob