如何防止DbModelBuilder构建的数据库模型连接到数据库?

时间:2017-02-23 14:56:46

标签: c# sql-server entity-framework

我需要使用SQL Server DbContext对Expression的支持进行单元测试。我很幸运地找到了this question亚瑟维克斯提供的非常丰富的回答。不幸的是,我在实施方面遇到了一些麻烦。

我已经从数据库中创建了一个带有自动生成DbContext的简单测试应用程序(我只添加了一个以DbCompiledModel为参数的构造函数):

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)
    {
    }
}

问题是我的代码仍然连接到数据库并从中打印数据:

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);
    }
}

我猜,该上下文从我的app.config文件中的连接字符串中获取数据库名称(但是为什么,如果我没有传递它?)。我已尝试从此连接字符串中删除数据库名称(&#34;初始目录&#34;参数),我的代码不会打印Foo&#39}。我想,这是解决方案,但后来我尝试编写并将新的Foo实体保存到上下文中:

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

下次执行代码时,会打印此实体。 SQL Server Management Studio没有看到任何新数据库或旧实体中的此实体,context.Database.Connection.Database是一个空字符串,所以看起来实体框架创建了一个空名称的数据库(甚至可能吗?)并将数据写入其中。

那么,有没有办法阻止上下文连接到数据库或创建新数据库?我的目标是至少运行context.Foos.Where(expression).ToList()而不连接到数据库并查看是否会出现异常,因为表达式无法转换为SQL查询。

非常感谢您的回答。

这是我的app.config文件:

<?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>

1 个答案:

答案 0 :(得分:0)

所以,看起来我误解了linked answer中提出的测试方式。我做了一些实验,发现用context.Foos.Where(expression)foreach迭代context.Foos.Where(expression).ToString()将使实体框架检查expression能够将其转换为SQL查询并创建数据库,如果它不存在。

但是在打电话之后:

Database.SetInitializer<TestDbContext>(null);
如果context.Foos.Where(expression).ToString()不正确,

expression仍然会检查expression并抛出异常,但它不会创建数据库。使用context.Foos.Where(expression) foreach迭代expression即使使用正确的expression也会因为无法创建数据库而引发异常。

所以,是的,可以测试实体框架是否支持foreach而不实际创建数据库或连接到现有数据库,但这只能通过调用&#39; ToString()&#来完成39;,它返回SQL查询或抛出异常。尝试使用 section {{44}} {{55}}

I need to copy the content of a <code></code> section using ClipboardJS. When following the tutorial, I end up with this error :

Uncaught Error: Invalid "target" value, use a valid Element

Any workaround on this ?

EDIT:

HTML

    <code id="#foo">my fantastic code</code>
    <button class="copy-button" data-clipboard-action="copy" data-clipboard-target="#foo">
      Copy !
    </button>

JAVASCRIPT

<script type="text/javascript">
  var clipboard = new Clipboard('.copy-button');

  clipboard.on('success', function(e) {
      console.info('Action:', e.action);
      console.info('Text:', e.text);
      console.info('Trigger:', e.trigger);

      e.clearSelection();
  });

  clipboard.on('error', function(e) {
      console.error('Action:', e.action);
      console.error('Trigger:', e.trigger);
  });
</script>