0

私は次の CMS に新しいものを使用してきましたが、MVCScaffoldingこれまでのところ素晴らしいものです。SQLExpressデフォルトのデータベースをSQLCeローカルデータベースに変更したくなるまでは素晴らしい。

ここ ( http://blog.stevensanderson.com/2011/01/13/scaffold-your-aspnet-mvc-3-project-with-the-mvcscaffolding-package/EFCodeFirst.SqlServerCompact ) には、「 」パッケージをインストールすると、それを変更し、データベース ファイルを作成します。だから私はそれをしました。

" " というファイルが作成されましたSQLCEEntityFramework.csが、そのファイルにはいくつかのエラーがありました。System.Data.Entity.Databaseもう存在しない「 」への参照と、DbDatabase現在存在する「 」への参照のようにDatabase。そこで、これらのエラーを修正してアプリケーションを実行しました。

すべてが通常どおり実行されていますが、接続文字列が my に追加されず、ディレクトリWeb.configにデータベース ファイルが作成されませんApp_Data。だから今、私は何か間違ったことをしているのだろうかと思い始めています...

ここで何が起こっているのか、それを修正する方法について何か手がかりを持っている人はいますか?

どうもありがとう。

編集: SQLCEEntityFramework.cs ファイルの内容を確認したい場合に備えて:

using System;
using System.Data.Entity;
using System.Data.SqlServerCe;
using System.IO;
using System.Transactions;
using System.Data.Entity.Infrastructure;

[assembly: WebActivator.PreApplicationStartMethod(typeof(CMS.App_Start.SQLCEEntityFramework), "Start")]

namespace CMS.App_Start {
    public static class SQLCEEntityFramework {
        public static void Start() {
            Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");

            // Sets the default database initialization code for working with Sql Server Compact databases
            // Uncomment this line and replace CONTEXT_NAME with the name of your DbContext if you are 
            // using your DbContext to create and manage your database
            //DbDatabase.SetInitializer(new CreateCeDatabaseIfNotExists<CONTEXT_NAME>());
        }
    }

    public abstract class SqlCeInitializer<T> : IDatabaseInitializer<T> where T : DbContext {
        public abstract void InitializeDatabase(T context);

        #region Helpers

        /// <summary>
        /// Returns a new DbContext with the same SqlCe connection string, but with the |DataDirectory| expanded
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        protected static DbContext ReplaceSqlCeConnection(DbContext context) {
            if (context.Database.Connection is SqlCeConnection) {
                SqlCeConnectionStringBuilder builder = new SqlCeConnectionStringBuilder(context.Database.Connection.ConnectionString);
                if (!String.IsNullOrWhiteSpace(builder.DataSource)) {
                    builder.DataSource = ReplaceDataDirectory(builder.DataSource);
                    return new DbContext(builder.ConnectionString);
                }
            }
            return context;
        }

        private static string ReplaceDataDirectory(string inputString) {
            string str = inputString.Trim();
            if (string.IsNullOrEmpty(inputString) || !inputString.StartsWith("|DataDirectory|", StringComparison.InvariantCultureIgnoreCase)) {
                return str;
            }
            string data = AppDomain.CurrentDomain.GetData("DataDirectory") as string;
            if (string.IsNullOrEmpty(data)) {
                data = AppDomain.CurrentDomain.BaseDirectory ?? Environment.CurrentDirectory;
            }
            if (string.IsNullOrEmpty(data)) {
                data = string.Empty;
            }
            int length = "|DataDirectory|".Length;
            if ((inputString.Length > "|DataDirectory|".Length) && ('\\' == inputString["|DataDirectory|".Length])) {
                length++;
            }
            return Path.Combine(data, inputString.Substring(length));
        }

        #endregion
    }

    /// <summary>
    /// An implementation of IDatabaseInitializer that will recreate and optionally re-seed the
    /// database only if the database does not exist.
    /// To seed the database, create a derived class and override the Seed method.
    /// </summary>
    /// <typeparam name="TContext">The type of the context.</typeparam>
    public class CreateCeDatabaseIfNotExists<TContext> : SqlCeInitializer<TContext> where TContext : DbContext {
        #region Strategy implementation

        public override void InitializeDatabase(TContext context) {
            if (context == null) {
                throw new ArgumentNullException("context");
            }
            var replacedContext = ReplaceSqlCeConnection(context);

            bool databaseExists;
            using (new TransactionScope(TransactionScopeOption.Suppress)) {
                databaseExists = replacedContext.Database.Exists();
            }

            if (databaseExists) {
                // If there is no metadata either in the model or in the databaase, then
                // we assume that the database matches the model because the common cases for
                // these scenarios are database/model first and/or an existing database.
                if (!context.Database.CompatibleWithModel(throwIfNoMetadata: false)) {
                    throw new InvalidOperationException(string.Format("The model backing the '{0}' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance. For example, the DropCreateDatabaseIfModelChanges strategy will automatically delete and recreate the database, and optionally seed it with new data.", context.GetType().Name));
                }
            }
            else {
                context.Database.Create();
                Seed(context);
                context.SaveChanges();
            }
        }

        #endregion

        #region Seeding methods

        /// <summary>
        /// A that should be overridden to actually add data to the context for seeding. 
        /// The default implementation does nothing.
        /// </summary>
        /// <param name="context">The context to seed.</param>
        protected virtual void Seed(TContext context) {
        }

        #endregion
    }

    /// <summary>
    /// An implementation of IDatabaseInitializer that will <b>DELETE</b>, recreate, and optionally re-seed the
    /// database only if the model has changed since the database was created.  This is achieved by writing a
    /// hash of the store model to the database when it is created and then comparing that hash with one
    /// generated from the current model.
    /// To seed the database, create a derived class and override the Seed method.
    /// </summary>
    public class DropCreateCeDatabaseIfModelChanges<TContext> : SqlCeInitializer<TContext> where TContext : DbContext {
        #region Strategy implementation

        /// <summary>
        /// Executes the strategy to initialize the database for the given context.
        /// </summary>
        /// <param name="context">The context.</param>
        public override void InitializeDatabase(TContext context) {
            if (context == null) {
                throw new ArgumentNullException("context");
            }

            var replacedContext = ReplaceSqlCeConnection(context);

            bool databaseExists;
            using (new TransactionScope(TransactionScopeOption.Suppress)) {
                databaseExists = replacedContext.Database.Exists();
            }

            if (databaseExists) {
                if (context.Database.CompatibleWithModel(throwIfNoMetadata: true)) {
                    return;
                }

                replacedContext.Database.Delete();
            }

            // Database didn't exist or we deleted it, so we now create it again.
            context.Database.Create();

            Seed(context);
            context.SaveChanges();
        }

        #endregion

        #region Seeding methods

        /// <summary>
        /// A that should be overridden to actually add data to the context for seeding. 
        /// The default implementation does nothing.
        /// </summary>
        /// <param name="context">The context to seed.</param>
        protected virtual void Seed(TContext context) {
        }

        #endregion
    }

    /// <summary>
    /// An implementation of IDatabaseInitializer that will always recreate and optionally re-seed the
    /// database the first time that a context is used in the app domain.
    /// To seed the database, create a derived class and override the Seed method.
    /// </summary>
    /// <typeparam name="TContext">The type of the context.</typeparam>
    public class DropCreateCeDatabaseAlways<TContext> : SqlCeInitializer<TContext> where TContext : DbContext {
        #region Strategy implementation

        /// <summary>
        /// Executes the strategy to initialize the database for the given context.
        /// </summary>
        /// <param name="context">The context.</param>
        public override void InitializeDatabase(TContext context) {
            if (context == null) {
                throw new ArgumentNullException("context");
            }
            var replacedContext = ReplaceSqlCeConnection(context);

            if (replacedContext.Database.Exists()) {
                replacedContext.Database.Delete();
            }
            context.Database.Create();
            Seed(context);
            context.SaveChanges();
        }

        #endregion

        #region Seeding methods

        /// <summary>
        /// A that should be overridden to actually add data to the context for seeding. 
        /// The default implementation does nothing.
        /// </summary>
        /// <param name="context">The context to seed.</param>
        protected virtual void Seed(TContext context) {
        }

        #endregion
    }
}
4

1 に答える 1

0

トム、

私もSqlCEとEntityFrameworkで問題が発生しています。しかし、私はそれを通り抜けて戦ったので、私はそれを使用することに精通しているので、あなたが参照している投稿を説明することができるかもしれません。

手始めに、そのブログエントリはMVCScaffoldingNuGetパッケージ用でした。このパッケージの機能を知っているかどうかはわかりませんが、基本的には、モデルを構築した後、Scott&CompanyがCRUDを動的に生成するために作成したScaffolderへの参照を追加します。

私の理解では、モデルを作成してプロジェクトをビルドしたら、パッケージマネージャーコンソールで次のコマンドを実行すると、上記のCRUDが作成されます。

Scaffold Controller [WhateverYourModelNameIs]

このプロセスが完了すると、Modelsフォルダーの下にアプリケーションのContextクラスが生成されます。上記のStartメソッドのコード(SQLCEEntityFramework.csの場合)に表示されている場合、データベースが存在しない場合にデータベースを作成するには、メソッドの最後の行のコメントを解除する必要があると記載されています。

最後に、アプリケーションを実行すると、SQL CEデータベースが作成され、App_Dataフォルダーをクリックして、ソリューションエクスプローラーの上部にある[すべてのファイルを表示]を選択し、[更新]アイコンをクリックすると、データベース。

アップデート:

申し訳ありませんが、これをテストした後、トム、あなたは正しいです。データベースを作成する唯一の方法は、Scaffolderによって作成されたビューの1つを実行する場合です。

于 2011-11-16T14:38:29.613 に答える