Использование базовых миграций Entity Framework для проекта библиотеки классов - PullRequest
0 голосов
/ 03 июля 2018

Кажется, это проблема, которая уже исправлена ​​, по крайней мере, для баз данных SQLite.

Мое решение состоит из 3 проектов:

  1. Проект WPF (запускаемый по умолчанию проект) ( .NET Framework 4.7 ),
  2. «Базовый» проект, содержащий модель представления и материал, не относящийся к пользовательскому интерфейсу - проект библиотеки классов ( .NET Standard 2.0 )
  3. «Реляционный» проект, содержащий все слои данных Entity Framework - мне нравится хранить их отдельно ( .NET Standard 2.0 )

Я установил следующие пакеты в основной проект WPF:

Microsoft.EntityFrameworkCore.Tools
Microsoft.EntityFrameworkCore.Design

Проекты 2 и 3 упоминаются в моем основном проекте WPF. В общем, EF должно быть достаточно для разрешения DbContextes.

Тем не менее, это не так - выполнение Add-Migration в моем проекте WPF приводит к:

PM> Add-Migration "Initial"
No DbContext was found in assembly 'TestWPFProject'. Ensure that you're using the correct assembly and that the type is neither abstract nor generic.

Переключение на проект 3 по умолчанию в консоли диспетчера пакетов приводит к:

PM> Add-Migration "Initial"
Unable to create an object of type 'ClientDbContext'. Add an implementation of 'IDesignTimeDbContextFactory<ClientDataStoreDbContext>' to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.

Как правильно использовать миграции EF Core с моим проектом библиотеки классов и проектом WPF?

Ответы [ 5 ]

0 голосов
/ 21 июня 2019

Я использовал проект библиотеки классов в качестве слоя данных и основной проект asp.net в качестве стартового проекта. Сначала я зарегистрировал свой базовый контекст E.F в классе запуска asp.net.

public void ConfigureServices(IServiceCollection services)
{
     //DataLayer namespace is in class library project
     services.AddDbContext<DataLayer.EFCoreContext>();
}

Затем в своем классе контекста (расположенном в проекте библиотеки классов) я предоставил строку соединения из установочного файла и использовал ее в методе OnConfiguring.

public class EFCoreContext: DbContext
{
        private string ConnectionString { get; set; }
        public EFCoreContext() : base()
        { 
            var settingsPath= AppDomain.CurrentDomain.BaseDirectory;
            settingsPath +=  @"\datalayersettings.json";
            var datalayersettings =File.ReadAllText(settingsPath);
            dynamic jSetting = JObject.Parse(datalayersettings);
            this.ConnectionString = 
                    (string)jSetting.ConnectionStrings.ConnectionString;
        }

        protected override void OnConfiguring(DbContextOptionsBuilder 
                                              optionsBuilder)
        {
            optionsBuilder.UseSqlServer(this.ConnectionString);
        }
}

затем для применения миграции и обновления базы данных я использовал следующие команды соответственно

add-migration MyEFCoreMigration -Context DataLayer.EFCoreContext -Project DataLayer

Update-Database -Context DataLayer.EFCoreContext -Project DataLayer
0 голосов
/ 18 декабря 2018

Что сработало для меня, так это просто делать свои обычные вещи в вашем UI Side Startup.cs

services.AddDbContext<ShentonEvaDbContext>(options =>
                options.UseSqlServer(
                    _configuration.GetConnectionString("DevelopmentConnection")));

Затем в вашей конфигурации DBContext просто добавьте конструктор

public ShentonEvaDbContext(DbContextOptions<ShentonEvaDbContext> options) : base(options)
        {

        }

После этого в консоли диспетчера пакетов просто запустите следующую команду

dotnet ef migrations add InitialMigration --project "NameOfDbContextProject" --startup-project "NameOfWebUIProject"

Затем добавили Everytihng и проделали то же самое для обновления базы данных

0 голосов
/ 05 июля 2018

Что microsoft предлагает здесь, это создать новую библиотеку классов для миграций, а затем переместить файлы снимков модели и миграции в новую библиотеку классов.

Если вы еще не добавили ни одного, добавьте его в проект DbContext и переместите его.

Затем настройте сборку миграции:

options.UseSqlServer(
    connectionString,
    x => x.MigrationsAssembly("MyApp.Migrations"));

А затем добавьте ссылку на вашу сборку миграции из вашей загрузочной сборки:

Примечание:

Если это вызывает циклическую зависимость, обновите выходной путь библиотеки классов:

<PropertyGroup>
  <OutputPath>..\MyStarupProject\bin\$(Configuration)\</OutputPath>
</PropertyGroup>

для второго использования Руководство Бена Кулла по миграции EntityFramework Core для проектов библиотеки классов.

0 голосов
/ 05 июля 2018

Я воспроизвел ваше решение и нашел ... решение:)

  1. «Основной» проект - называется ClassLibrary1
  2. «Реляционный» проект - называется EFClssLibrary
  3. Проект приложения WPF - называется WpfApp1

Давай углубимся.


1. Основной проект

Имя : ClassLibrary1 .

Тип : .NET Standard 2.0 библиотека классов .

Зависимости : нет.

В моем тестовом решении оно содержит только один класс, модель под названием Person .

Person.cs

namespace ClassLibrary1
{
    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Surname { get; set; }
    }
}

2. Реляционный проект

Имя : EFClassLibrary .

Тип : .NET Standard 2.0 библиотека классов .

Зависимости :

Этот проект в моем тестовом решении содержит только один класс: контекст базы данных.

ClientDbContext.cs

using ClassLibrary1;
using Microsoft.EntityFrameworkCore;

namespace EFClassLibrary
{
    public class ClientDbContext : DbContext
    {
        const string connectionString = "Server=(localdb)\\mssqllocaldb;Database=ClientDb;Trusted_Connection=True;";

        public ClientDbContext() : base() { }

        public ClientDbContext(DbContextOptions<ClientDbContext> options) : base(options) { }

        public DbSet<Person> People { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(connectionString);
        }
    }
}

Строка подключения

В этом классе определена используемая строка подключения для подключения к базе данных (при условии, что это SQL Server LocalDb). Если вы хотите поместить строку подключения в файл конфигурации, вы можете добавить общий файл конфигурации в свое решение, а затем сослаться на этот файл в файле App.config (для получения дополнительной информации посмотрите эту страницу )

Настройка целевой структуры

Чтобы иметь возможность добавлять миграции в этот проект, не устанавливая в качестве стартового проекта другие проекты, необходимо установить целевую среду. Щелкните правой кнопкой мыши на проекте и выберите запись Edit EFClassLibrary.csproj . Ниже строки <TargetFramework>netstandard2.0</TargetFramework> вы должны добавить еще одну строку, в которой указывается, на какую платформу вы хотите ориентироваться. Для нацеливания на .NET Framework 4.7 вы должны добавить

<TargetFramework>net47</TargetFramework>

Список всех допустимых значений можно найти здесь .

My EFClassLibrary.csproj выглядит как приведенный ниже код после добавления .NET Framework 4.7 в качестве цели.

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
    <TargetFramework>net47</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.1.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.1.1" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj" />
  </ItemGroup>

</Project>

Добавление миграций

Теперь вы готовы добавить свою первую миграцию. Откройте консоль диспетчера пакетов и установите в качестве проекта по умолчанию EFClassLibrary . Кроме того, установите этот проект в качестве запускаемого проекта (щелкните правой кнопкой мыши проект и выберите запись Установить в качестве запуска проекта ).

Тип

PM> Add-Migration Initial

тогда

PM> Update-Database

3. Проект приложения WPF

Имя : WpfApp1 .

Тип : Приложение WPF с использованием .NET Framework 4.7 .

Зависимости :

В этом проекте я не добавил файлов. Просто отредактировал файл MainWindow.xaml.cs, чтобы убедиться, что все работает правильно.

MainWindow.xaml.cs

using ClassLibrary1;
using EFClassLibrary;
using System.Windows;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            var db = new ClientDbContext();

            db.People.Add(new Person()
            {
                Name = "Omar"
            });

            db.SaveChanges();
        }
    }
}

Надеюсь, это поможет:)

0 голосов
/ 05 июля 2018

В вашем стартапе вы должны создать фабрику, которая будет реализовывать IDesignTimeDbContextFactory и создать DBContext для вас.

public class DBContextFactory : IDesignTimeDbContextFactory<DBContext>
        {
            public DBContext CreateDbContext(string[] args)
            {
                var optionsBuilder = new DbContextOptionsBuilder<DBContext>();

                // Row numbers for paging adds support for old SQL server 2005+. See more: 
                // https://docs.microsoft.com/en-us/ef/core/api/microsoft.entityframeworkcore.infrastructure.sqlserverdbcontextoptionsbuilder
                optionsBuilder.UseSqlServer("Server=localhost;Database=DatabaseName;Trusted_Connection=True;MultipleActiveResultSets=true;Integrated Security=SSPI", x => x.UseRowNumberForPaging());

                return new DBContext(optionsBuilder.Options);
            }
        }
...