У нас есть проект, который использует Entity Framework для CRUD-данных в / из базы данных.
Сейчас я пытаюсь написать шаблон T4, который использует доступ EF для генерации тестовых данных в форме кода, например var users = new List<User>{ new User {...}, new User {...} };
.
Когда я пытаюсь получить доступ к функциям, которые получают данные изDB, я получаю сообщение об ошибке, в котором говорится, что поставщик Entity Framework не возвратил объект, который унаследован от System.Data.Entity.Core.Common.DbProviderServices.
Хорошо, на минуту забудем об ошибке: МойПредполагается, что сборка, которая заботится о Entity Framework Access, обычно загружаемой из каталога bin\debug\
, теперь загружается из рабочего каталога Visual Studio, который находится где-то в каталоге C:\Program Files (x86)\
.Это приводит к тому, что можно найти разные сборки.Я не хочу использовать абсолютные пути для всех необходимых сборок, потому что это может вызвать проблемы у моих коллег, которые могут иметь другую конфигурацию на своих ПК.
Можно ли указать шаблон для запуска из$ (SolutionDir)?
РЕДАКТИРОВАТЬ
Я думаю, что я на шаг впереди: скрипт ниже запрашивает запись в App.config для соединениястрока, которой, в свою очередь, нет в рабочем каталоге Visual Studio.
<#@ template debug="true" hostspecific="false" language="C#" compileOptions="-P $(SolutionDir)Wur.Epros.Core" #>
<#@ assembly name="System" #>
<#@ assembly name="System.Configuration" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Data" #>
<#@ assembly name="System.Data.Common" #>
<#@ assembly name="System.Data.DataSetExtensions" #>
<#@ assembly name="System.Data.Entity" #>
<#@ assembly name="System.IO.Compression" #>
<#@ assembly name="System.Runtime.Serialization" #>
<#@ assembly name="System.Security" #>
<#@ assembly name="System.ServiceModel" #>
<#@ assembly name="System.Transactions" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="Microsoft.CSharp" #>
<#@ assembly name="System.ComponentModel.DataAnnotations" #>
<#@ assembly name="$(SolutionDir)packages\CuttingEdge.Conditions.1.2.0.0\lib\NET35\CuttingEdge.Conditions.dll" #>
<#@ assembly name="$(SolutionDir)packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll" #>
<#@ assembly name="$(SolutionDir)packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll" #>
<#@ assembly name="$(SolutionDir)packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll" #>
<#@ assembly name="$(SolutionDir)packages\NLog.4.5.11\lib\net45\NLog.dll" #>
<#@ assembly name="$(SolutionDir)packages\Oracle.ManagedDataAccess.12.2.1100\lib\net40\Oracle.ManagedDataAccess.dll" #>
<#@ assembly name="$(SolutionDir)packages\Oracle.ManagedDataAccess.EntityFramework.12.2.20190115\lib\net45\Oracle.ManagedDataAccess.EntityFramework.dll" #>
<#@ assembly name="$(SolutionDir)packages\structuremap.2.6.3\lib\StructureMap.dll" #>
<#@ assembly name="$(SolutionDir)Wur.Epros.Core\bin\debug\Wur.Epros.Core.dll" #>
<#@ assembly name="$(SolutionDir)Wur.Epros.Core.Tests\bin\debug\Wur.Epros.Core.Tests.dll" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="Wur.Epros.Core.Domain" #>
<#@ import namespace="Wur.Epros.Core.Infrastructure" #>
<#@ import namespace="Wur.Epros.Core.Tests.Mock" #>
<#@ import namespace="System.Data.Entity" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="StructureMap" #>
<#@ import namespace="Wur.Epros.Core.Infrastructure.StructureMap" #>
<#@ import namespace="Oracle.ManagedDataAccess.Client" #>
<#@ output extension=".cs" #>
// Test
<#
try
{
ObjectFactory.Configure(x =>
{
x.AddRegistry<CoreRegistry>();
x.Scan(scan =>
{
scan.WithDefaultConventions();
scan.LookForRegistries();
scan.TheCallingAssembly();
});
});
Wur.Epros.Core.Infrastructure.Environment.InitEnvironment();
DataClass.GenerateData<EPROS_SETUP>(DataClass.GetData<EPROS_SETUP>());
}
catch(Exception ex)
{
#>
/* <#= ex.Message #>
<#= ex.InnerException == null ? "null" : ex.InnerException.Message #> */
<#
}
#>
РЕДАКТИРОВАТЬ 2
Еще один шаг ближе к решению этой проблемы, но все еще не существует.Я добавил следующий код для инициализации сценария выше (также немного отредактирован).
using System.Configuration;
using System.Data.Entity;
namespace Wur.Epros.Core.Infrastructure
{
/// <summary>
/// Environment variables
/// </summary>
public static class Environment
{
public static void InitEnvironment()
{
DbConfiguration conf = new MyConf();
DbConfiguration.SetConfiguration(conf);
}
}
public class MyConf : DbConfiguration
{
public MyConf()
{
SetDefaultConnectionFactory(new System.Data.Entity.Infrastructure.LocalDbConnectionFactory("v13.0"));
SetProviderServices("System.Data.SqlClient", System.Data.Entity.SqlServer.SqlProviderServices.Instance);
SetProviderServices("Oracle.ManagedDataAccess.Client", Oracle.ManagedDataAccess.EntityFramework.EFOracleProviderServices.Instance);
}
}
}
Теперь я получаю следующую ошибку:
[A]Oracle.ManagedDataAccess.Client.OracleConnection cannot be cast to [B]Oracle.ManagedDataAccess.Client.OracleConnection. Type A originates from 'Oracle.ManagedDataAccess, Version=4.122.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342' in the context 'Default' at location 'c:\program files (x86)\oracle developer tools for vs2017\odp.net\managed\common\oracle.manageddataaccess.dll'. Type B originates from 'Oracle.ManagedDataAccess, Version=4.122.1.0, Culture=neutral, PublicKeyToken=89b483f429c47342' in the context 'LoadFrom' at location 'C:\Users\<userId>\AppData\Local\assembly\dl3\15K0NR5V.AGY\O2O039L7.GXW\137c2a2f\00141e2f_86d5d201\Oracle.ManagedDataAccess.dll'.
Он пытается загрузить сборку из 2 разных мест.Я предполагаю, что во втором месте процесс T4 временно хранит сборки.