Невозможно использовать существующую базу данных в модульных тестах с Effort Framework
Я пытаюсь написать тест, используя базу данных, размещенную в Azure SQL, с Effort Framework на Entity Framework 6.
При выполнении следующего кода выдается исключение:
[ClassInitialize]
public static void ClassInitialize(TestContext context)
{
EffortProviderConfiguration.RegisterProvider();
}
[TestMethod]
public void TestMethod1()
{
const string connectionString = "Data Source=***;Initial Catalog=my_catalog;User ID=user;Password=password;provider=System.Data.SqlClient";
IDataLoader loader = new EntityDataLoader(connectionString);
using (var ctx = new UsersDbContext(Effort.DbConnectionFactory.CreatePersistent("cool", loader)))
{
var usersCount = ctx.Users.Count();
}
}
Исключение брошено в Count()
выполнение:
Effort.Exceptions.EffortException: необработанное исключение при попытке инициализировать содержимое таблицы "Таблица" ---> System.ArgumentException: ключевое слово не поддерживается: "источник данных".
Такое же исключение выдается при замене EffortProviderConfiguration.RegisterProvider()
с настройками app.config.
При использовании точно такой же строки подключения для создания UsersDbContext
это успешно, и данные доступны. Кроме того, создание контекста в постоянном или временном режиме Effort без строки подключения также работает хорошо.
Что нужно сделать, чтобы инициализировать соединение с существующими данными из реальной БД?
3 ответа
Если, как и я, вы не понимаете, почему вы вообще должны предоставлять Effort строку подключения (поскольку она работает с базой данных в памяти, и вы предоставляете свой контекст для подключения напрямую), документация делает это немного более понятным - это требуется только в том случае, если вы используете варианты Entity Framework для базы данных или для модели, потому что строка подключения Entity предоставляет информацию, необходимую Effort для определения местоположения вашей модели, чтобы она могла построить из нее схему!! Таким образом, вы можете безопасно заполнить части строки подключения сервером / базой данных / идентификатором пользователя / паролем фиктивными именами.
Это также проясняет, что пользовательский подход DbConnectionFactory по умолчанию работает только для первого кода, который объясняет первые несколько часов ошибок, которые я получаю... Для модели сначала или для базы данных сначала вы должны внедрить Entity Connection в ваш класс сущности, как описано здесь.
Полезный совет: поскольку сгенерированный класс модели сущностей является частичным классом, вы можете создать другой файл кода в той же сборке, присвоить ему то же пространство имен и сделать его также частичным классом, а также добавить второй конструктор, необходимый для установки Вместо этого EntityConnection к этому файлу кода, таким образом, когда вы изменяете / воссоздаете свою модель сущности, код с пользовательским конструктором не будет удален шаблоном t4.
Вы указываете строку подключения в неправильном формате. Вы используете формат строки подключения ADO.NET/Linq2SQL, когда EntityDataLoader требует строку подключения, которая будет соответствовать EntityConnection (класс из EntityFramework). Вы можете прочитать о строках подключения для EF здесь: http://msdn.microsoft.com/en-us/library/system.data.entityclient.entityconnection.connectionstring(v=vs.110).aspx
Говоря коротко, ваша строка подключения должна выглядеть так:
"Provider=System.Data.SqlClient;
Metadata=c:\metadata|c:\Metadata\Sql;
Provider Connection String='Data Source=localhost; Initial Catalog=AdventureWorks;Integrated Security=True;Connection Timeout=60' "
Прямо сейчас в вашем коде вы указываете только часть строки подключения провайдера.
Я считаю, что ваша строка подключения должна быть указана в виде строки подключения в стиле EF. Например, в вашем app.config или в вашем webconfig:
<add name="dbConnectionString" connectionString="metadata=res://*/Models.YourEntityModel.csdl|res://*/Models.YourEntityModel.ssdl|res://*/Models.YourEntityModel.msl;provider=System.Data.SqlClient;provider connection string="data source=yourdatasource;initial catalog=yourdb;persist security info=True;user id=username;password=password;multipleactiveresultsets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
[TestMethod]
public void MyTestMethod()
{
//Arrange
//Then you can specify your connection string with its name:
EntityConnection connection =
Effort.EntityConnectionFactory.CreateTransient("name=dbConnectionString");
//Act
var usersCount;
using (MyDbContext ctx= new MyDbContext(connection))
{
usersCount = ctx.Users.Count();
}
//Assert
//Put your assert logic here:
Assert.IsTrue(usersCount == 100);
}