2017-02-23 2 views
0

Ich muss die Unterstützung von Expression Expression mit einem SQL Server DbContext Unit testen. Ich hatte das Glück, this question mit einer sehr informativen Antwort von Arthur Vickers zu finden. Leider habe ich Probleme mit der Implementierung.Wie verhindert man, dass das von DbModelBuilder erstellte Datenbankmodell eine Verbindung zur Datenbank herstellt?

ich einen einfachen Test-App mit automatisch generierten DbContext aus einer Datenbank erstellt haben (ich habe nur einen Konstruktor hinzugefügt, die DbCompiledModel als Argument):

public partial class TestDbContext : DbContext 
{ 
    public TestDbContext() : base("name=TestDbContext") 
    { 
    } 

    public TestDbContext(DbCompiledModel model) : base(model) 
    { 
    } 

    public virtual DbSet<Foo> Foos { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
    } 
} 

Das Problem ist, dass mein Code noch zu Datenbank verbindet und drucken Daten aus:

var dbModelBuilder = new DbModelBuilder(); 
dbModelBuilder.Entity<Foo>().HasEntitySetName("Foos"); 
var model = dbModelBuilder.Build(new DbProviderInfo("System.Data.SqlClient", "2012")); 
var compiledModel = model.Compile(); 

Database.SetInitializer<TestDbContext>(null); 

using (var context = new TestDbContext(compiledModel)) 
{ 
    foreach (var foo in context.Foos) 
    { 
     Console.WriteLine(foo.Name); 
    } 
} 

ich denke, den Ball zu Kontextdatenbanknamen von Verbindungszeichenfolge in meiner app.config-Datei (aber warum, wenn ich es nicht bin vorbei?). Ich habe versucht, Datenbankname ("initial catalog" param) aus dieser Verbindungszeichenfolge zu entfernen und mein Code no Foo 's gedruckt. Ich dachte, dass es die Lösung, aber dann habe ich versucht, neue Foo Einheit Kontext zu schreiben und speichern:

context.Foos.Add(new Foo() { Name = "Bar" }); 
context.SaveChanges() 

Das nächste Mal, wenn ich den Code dieser Einheit gedruckt wurde ausgeführt. SQL Server Management Studio sieht keine neuen Datenbanken oder diese Entität in der alten und context.Database.Connection.Database war eine leere Zeichenfolge. Es sieht also so aus, als ob Entity Framework eine Datenbank mit leerem Namen erstellt (ist das überhaupt möglich?) Und Daten dorthin geschrieben hat.

Gibt es also eine Möglichkeit zu verhindern, dass der Kontext mit der Datenbank verbunden oder neu erstellt wird? Mein Ziel ist es, zumindest context.Foos.Where(expression).ToList() ohne Verbindung zur Datenbank laufen zu lassen und zu sehen, ob es eine Ausnahme gibt, weil der Ausdruck nicht in eine SQL-Abfrage umgewandelt werden kann.

Vielen Dank für Ihre Antworten.

Hier ist meine app.config Datei:

<?xml version="1.0" encoding="utf-8"?> 
<configuration> 
    <configSections> 
     <section name="entityFramework" 
       type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
        requirePermission="false" /> 
    </configSections> 
    <startup> 
     <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" /> 
    </startup> 
    <entityFramework> 
     <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"> 
      <parameters> 
       <parameter value="mssqllocaldb" /> 
      </parameters> 
     </defaultConnectionFactory> 
     <providers> 
      <provider invariantName="System.Data.SqlClient" 
         type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> 
     </providers> 
    </entityFramework> 
    <connectionStrings> 
     <add name="TestDbContext" 
      connectionString="data source=INSPIRON;initial catalog=TestDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" 
      providerName="System.Data.SqlClient" /> 
    </connectionStrings> 
</configuration> 

Antwort

0

Also, es sieht aus wie ich die Art und Weise der Prüfung in linked answer vorgeschlagen falsch verstanden. Ich machte einige Experimente und fand heraus, dass beide context.Foos.Where(expression) mit foreach durchlaufen und context.Foos.Where(expression).ToString() aufrufen Entity Framework überprüfen expression für die Fähigkeit, es in SQL-Abfrage zu konvertieren und Datenbank erstellen, wenn es nicht existiert.

Aber nach dem Aufruf:

Database.SetInitializer<TestDbContext>(null); 

context.Foos.Where(expression).ToString() noch expression überprüfen und Ausnahme auslösen, wenn expression nicht korrekt ist, aber es wird nicht Datenbank erstellen. Iterating durch context.Foos.Where(expression) mit foreach sogar mit der richtigen expression wird Ausnahme wegen der Unfähigkeit, Datenbank zu erstellen.

Also, ja, ist es möglich, zu prüfen, ob expression von Entity Framework unterstützt wird, ohne tatsächlich Datenbank zu erstellen oder eine Verbindung zu einem bestehenden, aber dies kann nur durch den Aufruf ‚ToString()‘ durchgeführt werden, die SQL-Abfrage zurückgibt oder wirft Ausnahme. Der Versuch, Entitäten mit foreach zu durchlaufen, wird trotzdem eine Verbindung zur Datenbank herstellen oder eine Ausnahme auslösen, daher ist sie für diese Art von Tests nicht geeignet. Und das war mein Fehler.

Vielleicht, all das war offensichtlich genug, aber nicht für mich, also hoffe ich, meine Antwort kann jemandem in der gleichen Situation helfen.

Verwandte Themen