Как заставить проект пользовательского интерфейса многоуровневого решения разрешать объекты EF, не ссылаясь на слой доступа к данным
Я работаю над приложением WinForms, которое состоит из трех слоев, каждый из которых представляет собой отдельный проект, а именно:
В проекте SampleNtierDAL есть класс DalServices, который определяется следующим образом:
namespace SampleNtierDAL
{
public class DalServices
{
public static List<Employee> GetEmployees()
{
List<Employee> employeeList = null;
using (SampleNtierEntities aSampleNtierEntitiesDbContext = new SampleNtierEntities())
{
employeeList = (from emp in aSampleNtierEntitiesDbContext.Employees select emp).ToList();
}
return employeeList;
}
}
}
В проекте SampleNtierBLL есть класс BllServices, определенный следующим образом:
namespace SampleNtierBLL
{
public class BllSerices
{
public static List<Employee> GetEmployees()
{
return DalServices.GetEmployees();
}
}
}
Проект SampleNtierUI имеет событие кнопки WinForm, которое должно запрашивать у BllServices список сотрудников следующим образом:
namespace SampleNtierUI
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnGetListOfEmployees_Click(object sender, EventArgs e)
{
List<Employee> anEmployeeList = BllSerices.GetEmployees();
}
}
}
Проблема здесь в том, что WinForm не может увидеть модель сущности с именем "Employee", которая была создана Entity Frameworks 6. Класс проекта SampleNtierBLL BllServices видит класс, потому что он ссылается на SampleNtierDAL и имеет оператор использования вверху для разрешения Сотрудник класса. Я думал о добавлении аналогичных ссылок в WinForm для разрешения класса Employee, но я видел в других статьях, что вы не должны ссылаться на уровень доступа к данным, но такие статьи не показывают, как решить эту проблему, которая у меня есть.
Может кто-нибудь показать мне, как получить модель Entity (класс Employee), распознаваемый пользовательским интерфейсом (WinForm), не делая ссылки на уровень доступа к данным, где Entity Framework генерирует Entity с именем Employee? Заранее спасибо.
Обновление к моему сообщению 05.11.2015 17:13
После дополнительного тестирования с помощью процедуры, которую я добавил в сообщении 05.11.2015, 15:14, я обнаружил, что он действительно работает и в Visual Studio 2015 с.NET 4.5.2.
Обновление к моему сообщению 05.11.2015 15:14:
Спасибо Реза за всю работу, которую вы вложили в предоставление информации об ответах. Мне не удалось заставить ваше решение работать с Visual Studio 2013 или Visual Studio 2015, поскольку оно задокументировано. Тем не менее, я нашел интернет-видео на Pluralsight.com от Джули Лерман, которое предлагает решение. В ее решении не упоминалось использование части управления NuGet, которую вы сделали, поэтому я добавил ее к миксу и в итоге получил рабочий проект. Видео Джули Лерман озаглавлено:
"Отделение сгенерированных классов доменов от EDMX" и находится здесь:
Объединив часть вашей процедуры с ее, я закончил следующими шагами, которые работают для меня в Visual Studio 2013, но не в Visual Studio 2015.
Мой образец изначально имел следующий проект:
- SampleNtierDAL
- SampleNtierBLL
- SampleNtierUI
К этому списку проектов я добавляю четвертый проект под названием SampleNtierModels, поэтому список теперь выглядит следующим образом:
- SampleNtierDAL
- SampleNtierBLL
- SampleNtierUI
- SampleNtierModels
Шаги для выполнения:1) Настройте ссылки на проект следующим образом:
- SampleNtierBLL ссылается на SampleNtierDAL и SampleNtierModels
- SampleNtierDAL ссылается на SampleNtierModels
- SampleNtierDAL не ссылается на какой-либо проект
- SampleNtierUI ссылается на SampleNtierBLL и SampleNtierModels
2) Затем запустите программу "Проводник" (инструмент для просмотра файлов файловой системы) и переместите файл ModelEmployee.tt из папки с файлами проекта DAL в папку с файлами моделей.
3) С помощью обозревателя решений Visual Studio перейдите в проект SampleNtierModels, щелкните правой кнопкой мыши и выберите "Добавить существующий элемент". В диалоговом окне выберите "Все файлы", чтобы увидеть файл ModelEmployee.tt, и выберите его, чтобы добавить его в проект (не выбирайте файл ссылок).
4) Затем выберите проект SampleNtierDAL, затем щелкните правой кнопкой мыши файл ModelEmployee.tt и удалите его, который также автоматически удалит все файлы.cs под ним. Когда это будет сделано, узел ModelEmployee.tt должен исчезнуть.
5) Выберите проект SampleNtierModels, затем щелкните узел ModelEmployee.tt, который откроет файл MoadelEmployee.tt в редакторе. В верхней части содержимого находится константная строка inputFile. Установите эту строку, чтобы найти файл ModelEmployee.edmx следующим образом:
const string inputFile = @"..\SampleNiter\SampleNtierDAL\ModelEmployee.edmx
5) Затем выберите проект SampleNtierDAL, откройте файл ModelEmployee.Context.tt, прокрутите вниз раздел, ссылающийся на предложения, и добавьте пространство имен SampleNtierModels, как показано ниже:
if (container.FunctionImports.Any())
{
#>
using System.Data.Entity.Core.Objects;
using System.Linq;
using SampleNtierModels;
<#
}
7) Выберите проект SampleNtierBLL, откройте файл BLLServices.cs и добавьте следующие операторы using:
using SampleNtierModels;
using SampleNtierDAL;
8) Выберите проект SampleNtierDAL, откройте файл DalServices.cs и добавьте следующий оператор using:
using SampleNtierModels;
7) Выберите проект SampleNtierUI, откройте файл Form1.cs и добавьте следующие операторы using:
using SampleNtierModels;
using SampleNtierBLL
8) Нажмите Инструменты в строке меню, затем Менеджер пакетов NuGet, затем
- Выберите установленные пакеты
- Поиск Entity Framework
- Выберите отображаемый пакет EntityFramework и нажмите кнопку "Управление"
- В окне списка убедитесь, что выбраны следующие параметры: SampleNtierBLL, SampleNtierDAL, SamleNtierUI
9) Выберите проект SampleNtierDAL, щелкните правой кнопкой мыши узел ModelEmployee.Context.tt и выберите "Запустить пользовательский инструмент".
10) Выберите проект SampleNtierModels, щелкните правой кнопкой мыши узел ModelEmployee.tt и выберите "Запустить пользовательский инструмент".
11) Скопируйте все содержимое файла App.Config в проекте SampleNtierDAL в файл App.Config проекта SampleNtierUI.
Ниже приведен пример изображения, показывающего, как проект выглядел в конце, а также пример сеанса отладки, показывающий 3 строки данных, возвращаемых из структуры сущностей, которые исходят из DAL, затем в BLL и, наконец, в пользовательский интерфейс. Пользовательский интерфейс Winform также показывает, что ссылка на DAL не нужна.
Эта проблема теперь решена, поэтому еще раз спасибо Реза за помощь в решении этой проблемы. Я оставил сообщение с Juile с просьбой обновить процесс здесь, который включает Visual Studio 2015.
1 ответ
Короткий ответ
Вы должны поместить свои модели в отдельный проект, чем ваш DAL
сделать ваши модели видимыми для User Interface (UI)
проект без ссылки Data Access Layer (DAL)
Проект. И все ваши проекты должны иметь ссылку на ваш проект модели.
Ключевой момент в этом с помощью Database/Model First
Подход "Добавить существующий элемент" в ваш проект моделей и выберите .tt
файл моделей и выберите Add as Link
из раскрывающегося списка кнопки Добавить в диалоговом окне.
Пошаговое руководство по созданию многоуровневого решения
Чтобы поместить ваши модели в отдельный проект с использованием структуры сущности, выполните следующие действия:
Создавать проекты
- Создайте проект и назовите его, например
Sample.DAL
- Создайте другой проект и назовите его
Sample.Models
- Создайте другой проект и назовите его
Sample.BLL
- Создайте другой проект и назовите его
Sample.UI
Конфигурация Ссылки
Добавьте ссылки на проекты с этими правилами:
Sample.UI
зависит отSample.BLL
а такжеSample.Models
Sample.BLL
зависит отSample.DAL
а такжеSample.Models
Sample.DAL
зависит отSample.Models
Sample.Models
не зависит от других проектов
Config Sample.DAL
- Добавьте свой
SampleDB.edmx
вSample.DAL
проект - расширять
Sample.edmx
узел и расширитьSampleDB.tt
узел и удалите все файлы.cs вSampleDB.tt
- В свойствах
SampleDB.tt
ЧистоCustomTool
Config Sample.Models
Add Existing Item
вSample.Models
и в диалоговом окне перейдите в папкуSample.DAL
и выбратьAll files
из поля со списком и выберитеSampleDB.tt
и нажмите на кнопку "Добавить" и в меню выберитеAdd As Link
- выберите
SampleDB.tt
и в свойствах установитеCustomToolNamespace
вSample.DAL
- Щелкните правой кнопкой мыши на
SampleDB.tt
а такжеRun Custom Tool
Управление пакетами Nuget
- Щелкните правой кнопкой мыши по решению и выберите
Manage Nuget Packages for Solution
и выберите установленные пакеты, выберитеEntity Framework
и нажмите Управление. выберитеSample.DAL
а такжеSample.BLL
а такжеSample.UI
Config Sample.BusinessLogic
Создать YourEntityBusinessLogic
класс с этим кодом:
public class YourEntityBusinessLogic
{
public List<YourEntity> GetAll()
{
var context = new YourDBContext();
return context.YourEntities.ToList();
}
}
Обратите внимание, чтобы не предоставлять YourDBContext в открытых свойствах или в качестве входных параметров методов и конструкторов или в качестве возвращаемых значений.
Config Sample.UI
Скопируйте строку подключения из
app.config
файл изSample.DAL
и вставьте вapp.config
изSample.UI
до<entityframework>
тег.Создать
Form
и установите его как запуск и запустить этот код в качестве теста вFormLoad
или где вы хотите:
//Shows count of records in your table
var business = new YourEntityBusinessLogic();
MessageBox.Show(business.GetAll().Count().ToString());
Структура решения
Вот структура решения, и, как вы видите, контекст находится в Sample.DAL
и модели в Sample.Models
,
Так что вам не нужно добавлять ссылку на DAL
в вашем UI
проект.