Как использовать сущностный каркас (сначала код) с динамически создаваемой строкой соединения и однофайловой базой данных? - PullRequest
2 голосов
/ 17 сентября 2011

Я использую SqlServerCompact, платформу Entity с первым кодом и генерирую строку подключения динамически, потому что база данных создается при запросе пользователем.

Я следовал советам из этого вопроса: Как программно установить строку подключения для Entity-Framework Code-First? однако, у меня все еще есть проблемы, в результате я получаю исключение, сообщающее, что схема в модели отличается от используемой в коде.

Это, однако, очевидно, я хочу, чтобы схема генерировалась из кода, поэтому я действительно не могу понять, почему это происходит

Может ли кто-нибудь мне помочь? Вот код, используемый:

NerdDinners.cs

class NerdDinners : DbContext
{
    public static string CreateConnectionString(string dbPath = @"|DataDirectory|\NerdDinners.sdf")
    {
        SqlCeConnectionStringBuilder sqlConnection = new SqlCeConnectionStringBuilder();
        sqlConnection.Password = "9023fase93";
        sqlConnection.DataSource = dbPath;

        EntityConnectionStringBuilder connection = new EntityConnectionStringBuilder();
        connection.Metadata = @"res://*/NerdDinnersModel.csdl|res://*/NerdDinnersModel.ssdl|res://*/NerdDinnersModel.msl";
        connection.Provider = "System.Data.SqlServerCe.3.5";
        connection.ProviderConnectionString = sqlConnection.ToString();

        return connection.ToString();
    }

    public NerdDinners() : base() { }
    public NerdDinners(string nameOrConnectionString) : base(nameOrConnectionString) { }

    public DbSet<Dinner> Dinners { get; set; }
    public DbSet<RSVP> RSVPs { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        Database.SetInitializer<NerdDinners>(new NerdDinnersInitializer());
        Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe");

        base.OnModelCreating(modelBuilder);
    }
}

Program.cs

class Program
{
    static void Main(string[] args)
    {
        NerdDinners nerdDinner = new NerdDinners(NerdDinners.CreateConnectionString());
        Console.WriteLine("Inizio test");

        var res = from d in nerdDinner.Dinners
                  select d;

        Console.WriteLine("Dinners:");
        foreach (var item in res)
            Console.WriteLine(item.ToString());
        Console.WriteLine("End");

        // Usato per terminazione
        Console.ReadKey();
    }
}

Это мое решение ситуации (изображение):

Solution rapresentation

РЕДАКТИРОВАТЬ 1:

Ошибка - MetadataException, он жалуется на недопустимую схему

РЕДАКТИРОВАТЬ 2:

NerdDinnersInitializer.cs

class NerdDinnersInitializer : DropCreateDatabaseAlways<NerdDinners>
{
    public NerdDinnersInitializer() : base() { }

    protected override void Seed(NerdDinners context)
    {
        var toadd = new List<Dinner>
        {
            new Dinner
            {
                Address = "bla",
                DinnerID = 0,
                EventDate = DateTime.Parse("2010-12-03"),
                HostedBy = "mclink",
                Title = "Notitle",
            },
            new Dinner
            {
                Address = "Fiwe",
                DinnerID = 0,
                EventDate = DateTime.Parse("2011-12-03"),
                HostedBy = "ngi",
                Title = "Bah",
            },
        };

        toadd.ForEach(item => context.Dinners.Add(item));

        context.SaveChanges();

        base.Seed(context);
    }
}

Ответы [ 2 ]

2 голосов
/ 17 сентября 2011

Я не уверен, применимо ли это к вашей ситуации, но вы можете получить ошибку, если модель не соответствует существующей схеме БД.Вам нужно сделать что-то похожее на это -

Database.SetInitializer<NerdDinners>(
    new DropCreateDatabaseIfModelChanges<NerdDinners>());

, который удалит существующую базу данных и создаст новую на основе вашей модели.

В вашем примере кода есть код, которыйустанавливает инициализатор -

Database.SetInitializer<NerdDinners>(new NerdDinnersInitializer());

, но я не уверен, что делает ваш NerdDinnersInitializer класс.

0 голосов
/ 18 сентября 2011

Я нашел ответ с глубоким поиском в Google. Я понял, что неправильно понял, как сначала работает код, на самом деле не может создать базу данных, к которой вы хотите подключиться , если вы используете code-first .

Я до сих пор не понимаю, можете ли вы сохранить в выбранном месте базу данных, сгенерированную с помощью кода вначале (я думаю, вы не можете).

Однако, если вы хотите подключиться к существующему файлу базы данных, вы должны использовать подход, основанный на модели или на основе базы данных , сначала нельзя использовать код

Это то, что я понял, надеюсь, я не ошибаюсь. Этот вопрос объясняет это лучше: Почему Entity Framework Code-First (с существующей БД) продолжает пытаться получить данные из таблицы EdmMetadata?

РЕДАКТИРОВАТЬ 1: Похоже, я ошибся, возможно, но вам нужен SQL Server compact 4.0, а не 3.5 (у меня были проблемы с ним), также вам нужно vs 2010 и Entity Framework 4.1. Затем просто следуйте ответу на этот вопрос, чтобы динамически создать строку: Можно ли создать базу данных (Sql Server compact) по заданному пути, если мы используем среду Entity с подходом, основанным на коде?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...