2011-01-19 31 views
41

Tôi có dự án asp.net MVC3 sử dụng mã EF đầu tiên. Đối với thử nghiệm đơn vị của tôi, tôi đã sử dụng SQL Server CE 4.0 và SQL Server 2008 Express. Cả hai đã làm việc hoàn hảo với EF tạo ra cơ sở dữ liệu của tôi như mong đợi.Cách cấu hình ProviderManifestToken cho Mã EF Đầu tiên

Tuy nhiên, khi tôi chạy ứng dụng của tôi bên ngoài của một thử nghiệm đơn vị và điểm nó ở chuỗi kết nối của tôi, tôi nhận được lỗi

ProviderIncompatibleException: Nhà cung cấp không trả về một chuỗi ProviderManifestToken

tôi đã đọc tài liệu MS về điều này và nó xuất hiện đây là một mã thông báo SqlVersion mà mô hình EF tạo ra. Vấn đề là tôi đang sử dụng phương pháp tiếp cận mã đầu tiên vì vậy tôi không có tệp .edmx cũng như tôi không biết nơi để trỏ thông tin siêu dữ liệu của mình đến vì db chưa được tạo.

Tôi biết chuỗi kết nối của mình theo tên db, tên người dùng và thông tin là chính xác vì thay đổi chúng thành giá trị sai sẽ ném lỗi dự kiến. Không chắc chắn bắt đầu từ đâu.

Cảm ơn.

Đây là chuỗi kết nối của tôi:

<connectionStrings> 
    <add 
    name="SqlConnection" 
    providerName="System.Data.SqlClient" 
    connectionString="Data Source=WORKSTATION\SQLEXPRESS;Initial Catalog=CodeFirst;Integrated Security=False; 
    Persist Security Info=False;User ID=CodeFirst_user;Password=password1;Connect Timeout=120;MultipleActiveResultSets=True;"/> 
</connectionStrings> 
+5

Bạn có chắc là chuỗi kết nối được sử dụng không? Nó sẽ có cùng tên với lớp của bạn bắt nguồn từ DbContext. –

+9

. Tôi thấy vấn đề là gì. Đó là một vài điều. (1) db không nên được tạo trước trong SqlServer ngay cả khi nó rỗng. Hãy để EF làm điều này. (2) Một tên danh mục ban đầu nên được bao gồm nếu nó không được khai báo trong DbContext. (3) Tôi không thể tạo db dưới Medium Trust. Hy vọng điều này sẽ giúp một ai đó. – trevorc

+1

@nameEquals ... bạn đã giải quyết mục 3 ở trên như thế nào? –

Trả lời

1

Tôi có vấn đề này khi làm việc thông qua các MVC3 tutorial on ASP.NET.

Giải pháp của tôi đã kết thúc là sử dụng (localhost) thay vì Nguồn dữ liệu được đặt tên. Điều này làm việc tốt trên hộp của tôi, cho công việc dev địa phương, nhưng sẽ không giúp đỡ nếu cơ sở dữ liệu trên một máy chủ riêng biệt.

6

Tôi chỉ gặp sự cố chính xác này nhưng tôi truy tìm dịch vụ SQL Server của mình không chạy. Tôi vừa mới khởi động lại máy tính của mình và thường nó bắt đầu trên máy tính của riêng nó nhưng không vì lý do nào đó.

+0

Tương tự ở đây. Tôi chỉ cần kiểm tra quản lý cấu hình SQL Server của tôi và dịch vụ Sql Server không chạy vì một lý do nào đó. Khi tôi bắt đầu dịch vụ, nó hoạt động hoàn hảo –

+0

Điều tương tự đối với tôi, nhưng dịch vụ SQLEXPRESS của tôi không hoạt động. Nó không hoạt động với SQL Server bình thường đang chạy. – Pieter

1

Tôi tìm thấy, khi tôi cung cấp rõ ràng "Id người dùng = abcUser; Mật khẩu = somePwd;" trong chuỗi kết nối của tôi, tôi có thể giải quyết cùng một lỗi. Trước đó tôi đã sử dụng "Trusted_Connection = true;", cho phép tôi gỡ lỗi dự án web của tôi, nhưng bắt đầu cho tôi lỗi - {"Nhà cung cấp không trả về chuỗi ProviderManifestToken."} Ngay sau khi tôi thêm dự án Windows Azure và đã thử gỡ lỗi dự án Azure sau khi thêm dự án web của tôi dưới dạng vai trò web bên dưới nó.

Hy vọng nó sẽ giúp một số người gặp phải tình huống tương tự.

Cảm ơn, Vivek Bahl

1

Thay đổi để Data Source = localhost làm việc cho tôi cũng sử dụng MS SQL 2008 R2 nhanh

0

này được chứng minh hữu ích cho tôi:

<connectionString="Data Source=WORKSTATION\SQLEXPRESS;Initial Catalog=CodeFirst;User ID=CodeFirst_user;Password=********"/> 
</connectionStrings> 
6

Trong trường hợp của tôi, tên chuỗi kết nối của tôi phải khớp với tên lớp ngữ cảnh.

Connection String:

<connectionStrings> 
    <add name="NunuContext" connectionString="Data Source=|DataDirectory|Nunu.sdf" providerName="System.Data.SqlServerCe.4.0" /> 
</connectionStrings> 

Context Class:

using System.Data.Entity; 
namespace Nunu.Models 
{ 
    public class NunuContext : DbContext 
    { 
     System.Data.Entity.DropCreateDatabaseIfModelChanges<Nunu.Models.NunuContext>()); 

     public DbSet<Nunu.Models.NunuFirst> NunuFirsts { get; set; } 

     public DbSet<Nunu.Models.NunuLast> NunuLasts { get; set; } 
    } 
} 
1

Thay đổi nguồn dữ liệu để localhost trong connectionString giải quyết vấn đề của tôi.

9

Sau nhiều giờ tìm kiếm & không quan trọng, tôi đã tìm được cách để thực hiện. Hóa ra lớp DbModelBuilder mất một DbProviderInfo trong phương pháp Build của nó, vì vậy tôi sử dụng thay vì dựa vào EF gọi OnModelCreated:

// 'Entities' is my DbContext subclass, the "container" in EF terms. 
public static Entities GetNewContext() 
{ 
    // Get a connection, for example: 
    var connection = new SqlConnection(GetConnectionString()); 

    // Create a DbModelBuilder 
    var modelBuilder = new DbModelBuilder(); 
    // Configure the model builder. 
    // I changed my DbContext subclass - added a public version of OnModelCreated and called it ConfigureModelBuilder 
    Entities.ConfigureModelBuilder(modelBuilder); 

    // Here's where the magic happens. 
    // Build the model and pass the ProviderManifestToken (I use 2005 to avoid a bug in precision of sql datetime columns when using concurrency control) 
    var model = modelBuilder.Build(new System.Data.Entity.Infrastructure.DbProviderInfo("System.Data.SqlClient", "2005")); 
    // Compile the model 
    var compiledModel = model.Compile(); 

    // Create the container (DbContext subclass). Ideally all the previous stuff should be cached. 
    return new Entities(connection, compiledModel, true); 
} 

Rõ ràng điều này cần một số tổ chức lại (ví dụ như bộ nhớ cache mô hình biên soạn, do đó bạn không cần để xây dựng lại nó mỗi khi một ngữ cảnh được tạo ra).

Đối với tôi, điều này đã giải quyết được hoàn toàn sự cố. Thưởng thức!

+1

Nice- ai đó cuối cùng đã trả lời câu hỏi từ tiêu đề của bài đăng !! – Shawson

+0

Đối với những người làm việc với các ứng dụng phải đính kèm vào nhiều phiên bản SQL, tôi đã xác nhận giải pháp này hoạt động khi kết nối với nhiều phiên bản SQL (2005 và 2008). – RMart

+0

Rất vui - Tôi ước mình đã thấy điều này trước đây! Hãy xem làm thế nào bạn có thể làm điều này một chút dễ dàng hơn trong EF 6 - xem câu trả lời của tôi dưới đây. – Olly

9

Nếu bạn đang sử dụng EF 6 (vừa mới phát hành), bạn có một giải pháp thay thế.

phụ thuộc Nghị quyết

Bạn có thể sử dụng tính năng mới dependency resolution để đăng ký một thực hiện IManifestTokenResolver (được mô tả trong this preview documentation như IManifestTokenService).

This article cung cấp thêm một chút thông tin về cách sử dụng DbConfiguration. Cách dễ nhất để sử dụng nó là như sau:

DbConfigurationType(typeof(EntityFrameworkDbConfiguration))] 
public class MyContextContext : DbContext 
{ 
} 

Ví dụ này tránh bất kỳ chuyến đi nào tới cơ sở dữ liệu khi tạo siêu dữ liệu cho kết nối SQL Server và tự động chỉ định tính tương thích của SQL Server 2005.

using System.Data.Common; 
using System.Data.Entity; 
using System.Data.Entity.Infrastructure; 
using System.Data.Entity.Infrastructure.DependencyResolution; 
using System.Data.SqlClient; 

/// <summary> 
/// A configuration class for SQL Server that specifies SQL 2005 compatability. 
/// </summary> 
internal sealed class EntityFrameworkDbConfiguration : DbConfiguration 
{ 
    /// <summary> 
    /// The provider manifest token to use for SQL Server. 
    /// </summary> 
    private const string SqlServerManifestToken = @"2005"; 

    /// <summary> 
    /// Initializes a new instance of the <see cref="EntityFrameworkDbConfiguration"/> class. 
    /// </summary> 
    public EntityFrameworkDbConfiguration() 
    { 
     this.AddDependencyResolver(new SingletonDependencyResolver<IManifestTokenResolver>(new ManifestTokenService())); 
    } 

    /// <inheritdoc /> 
    private sealed class ManifestTokenService : IManifestTokenResolver 
    { 
     /// <summary> 
     /// The default token resolver. 
     /// </summary> 
     private static readonly IManifestTokenResolver DefaultManifestTokenResolver = new DefaultManifestTokenResolver(); 

     /// <inheritdoc /> 
     public string ResolveManifestToken(DbConnection connection) 
     { 
      if (connection is SqlConnection) 
      { 
       return SqlServerManifestToken; 
      } 

      return DefaultManifestTokenResolver.ResolveManifestToken(connection); 
     } 
    } 
} 
+0

Có phải những thứ như thế này cần thiết để sử dụng EF với ODP.NET mà không thực sự kết nối với cơ sở dữ liệu? –

+2

@ObliviousSage Tôi chưa bao giờ sử dụng EF với Oracle, nhưng từ [bài viết này] (http://www.codeproject.com/Tips/524041/Entity-Framework-ProviderManifestToken-not-valid) có vẻ như bạn đang làm * * cần phải làm một cái gì đó như thế này. Tác giả của bài báo thấy rằng "11g" là giá trị mã thông báo thích hợp trong trường hợp của anh ta. – Olly

Các vấn đề liên quan