实体框架 - 冗余连接字符串

发布于 2024-09-24 14:31:22 字数 1481 浏览 1 评论 0 原文

我在我的项目中使用实体框架 4。该框架已创建自己的连接字符串,因此我的 web.config connectionStrings 部分文件如下所示:

  <connectionStrings>
    <add name="ApplicationServices" connectionString="data source=localhost;user id=user;pwd=pass;initial catalog=VNK" providerName="System.Data.SqlClient" />    
    <add name="VNKEntities" connectionString="metadata=res://*/VNKModel.csdl|res://*/VNKModel.ssdl|res://*/VNKModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=localhost;Initial Catalog=VNK;User ID=user;Password=pass;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>

第一个名为 ApplicationServices 的连接字符串是我原来的连接字符串。第二个名为 VNKEntities 是在生成模型时创建的。

当我检查生成的 *.edmx 文件时,我发现该模型正在引用其连接字符串,如下所示:

    /// <summary>
    /// Initializes a new VNKEntities object using the connection string found in the 'VNKEntities' section of the application configuration file.
    /// </summary>
    public VNKEntities() : base("name=VNKEntities", "VNKEntities")
    {
        this.ContextOptions.LazyLoadingEnabled = true;
        OnContextCreated();
    }

我的问题是如何摆脱 VNKEntities 连接字符串,只保留 ApplicationServices,我将从我的模型中引用它?我只想有一个到数据库的连接字符串,因为我只使用一个数据库(将构造函数参数从 name=VNKEntities 替换为 name=ApplicationServices 是不可行的在职的)。

问候

I'm using Entity Framework 4 in my project. The Framework has created its own connection string, so my web.config connectionStrings section file looks following:

  <connectionStrings>
    <add name="ApplicationServices" connectionString="data source=localhost;user id=user;pwd=pass;initial catalog=VNK" providerName="System.Data.SqlClient" />    
    <add name="VNKEntities" connectionString="metadata=res://*/VNKModel.csdl|res://*/VNKModel.ssdl|res://*/VNKModel.msl;provider=System.Data.SqlClient;provider connection string="Data Source=localhost;Initial Catalog=VNK;User ID=user;Password=pass;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" />
  </connectionStrings>

The first connection string called ApplicationServices is my original one. The second, called VNKEntities has been created while generating the model.

When I checked the generated *.edmx file, I found that this model is referencing its connection string, which is shown below:

    /// <summary>
    /// Initializes a new VNKEntities object using the connection string found in the 'VNKEntities' section of the application configuration file.
    /// </summary>
    public VNKEntities() : base("name=VNKEntities", "VNKEntities")
    {
        this.ContextOptions.LazyLoadingEnabled = true;
        OnContextCreated();
    }

My question is how can I get rid of the VNKEntities connection string, and leave only ApplicationServices, to which I will be referencing from my model? I would like to have only one connection string to the database, because I'm using only one database (replacing the constructor parameter from name=VNKEntities to name=ApplicationServices is not working).

Regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

千年*琉璃梦 2024-10-01 14:31:23
  1. 从普通连接字符串手动创建 DbConnection
  2. 手动创建 MetadataWorkspace 对象。
  3. 使用 EntityConnection http://msdn.microsoft.com/en-us/library/cc679371.aspx" rel="nofollow noreferrer">此作者<​​/a>。
  4. 将实体连接传递给 ObjectContext 构造函数。
  1. Manualy create DbConnection from ordinary connection string
  2. Manualy create MetadataWorkspace object.
  3. Create EntityConnection using this ctor.
  4. Pass entity connection to ObjectContext constructor.
夏雨凉 2024-10-01 14:31:23

我也有同样的问题。我通过以下方式解决了这个问题:

我创建了两个 edmx 文件,但是在创建第二个 edmx 文件时,我忽略了要保存在配置文件中的连接字符串。这样我的配置文件将只保存一个连接字符串。
然后我修改了连接字符串中的以下几行:

<add name="MyDbContext" connectionString="metadata=res://*/;provider=System.Data.SqlClient;provider connection string="data source=abc;initial catalog=mydb;persist security info=True;user id=myuser;password=password;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />

只需将“res://model1.csdl”替换为 “res://*/”,它就像一个魅力。

您可以在 dbcontext 类的构造函数中指定此连接名称,如下所示:

public MyDbContext() : base("name=NameOfYourConnectionString") //  Name of your connection string
{ }

注意:我使用的是 Entity Framework 5.0。

I had the same problem. I have solved it by following way:

I have created two edmx file, but while creating second edmx file, i ignored the connection string to be save in config file. This way my config file will hold only one Connection string.
Then i modified following lines in my connection string:

<add name="MyDbContext" connectionString="metadata=res://*/;provider=System.Data.SqlClient;provider connection string="data source=abc;initial catalog=mydb;persist security info=True;user id=myuser;password=password;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />

Just replace "res://model1.csdl" with "res://*/" and it works like a charm.

You can specify this connection name in constructor of your dbcontext class like:

public MyDbContext() : base("name=NameOfYourConnectionString") //  Name of your connection string
{ }

Note: I am using Entity Framework 5.0.

记忆消瘦 2024-10-01 14:31:23

我将提供解决此问题的完整实现(基于 gandjustas 提示)。我为上下文编写了一个简单的包装器,可以按以下方式使用:

using (var wrapper = new ContextWrapper<VNKEntities>())
{
    // do your stuff based on wrapper.Context
}

类型 ContextWrapper 是一个模板,它简单地包装了上下文,该上下文只是以稍微另一种方式构造的(仅使用一个连接字符串),然后通过属性公开。它的内部实现如下:

public class ContextWrapper<TContext> : IDisposable
    where TContext : ObjectContext
{
    private TContext _context;
    private EntityConnectionManager _manager;
    private bool _disposed;

    public ContextWrapper()
        : this(true)
    {
    }

    public ContextWrapper(bool lazyLoadingEnabled)
    {
        _disposed = false;
        _manager = new EntityConnectionManager();
        _context = (TContext)Activator.CreateInstance(typeof(TContext), _manager.Connection);  
        _context.ContextOptions.LazyLoadingEnabled = lazyLoadingEnabled;
    }

    ~ContextWrapper()
    {
        Dispose(false);
    }

    public TContext Context
    {
        get { return _context; }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);

    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                if (_manager != null)
                {
                    _manager.Dispose();
                    _manager = null;
                }
                var ctx = _context as IDisposable;
                if (ctx != null)
                {
                    ctx.Dispose();
                    _context = null;
                }
            }
        }
        _disposed = true;
    }
}

您可以看到名为 EntityConnectionManager 的自定义类的用法:

internal class EntityConnectionManager : IDisposable
{
    private DbConnection _connection;
    private EntityConnection _entityConnection;

    private volatile bool _disposed;

    public EntityConnectionManager()
    {
        var workspace = new MetadataWorkspace(Setting.MetadataWorkspacePaths.Split('|'), new[] { Assembly.ReflectionOnlyLoad(Setting.MetadataAssemblyNameToConsider) });

        _connection = new SqlConnection(Setting.ConnectionString);
        _entityConnection = new EntityConnection(workspace, _connection);
        _disposed = false;
    }

    public EntityConnection Connection
    {
        get { return _entityConnection; }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                if (_connection != null)
                {
                    _connection.Dispose();
                    _connection = null;
                }
                if (_entityConnection != null)
                {
                    _entityConnection.Dispose();
                    _entityConnection = null;
                }
            }
        }
        _disposed = true;
    }
}

因此,现在您可以拥有一个连接字符串:

<connectionStrings>
  <add name="ApplicationServices" connectionString="data source=localhost;user id=user;pwd=pass;initial catalog=VNK;Pooling=False;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />    
</connectionStrings>

以及在应用程序设置部分中定义的元数据(第二个关键点指向您所在的程序集)域模型实际上是存储的):

<appSettings>
  <add key="MetadataWorkspacePaths" value="res://*/VNKModel.csdl|res://*/VNKModel.ssdl|res://*/VNKModel.msl" />
  <add key="MetadataAssemblyNameToConsider" value="VNK.Models" />
</appSettings>

Setting 类型的逻辑很简单,因为它只是从配置文件中提取设置。

I'll provide complete implementation I did to resolve this issue (based on gandjustas hints). I've written a simple wrapper for the context, which can be used in the following manner:

using (var wrapper = new ContextWrapper<VNKEntities>())
{
    // do your stuff based on wrapper.Context
}

Type ContextWrapper is a template which simply wraps the context which is just constructed in a slightly other way (using only one connection string) and then exposed by property. Its internal implementation is placed below:

public class ContextWrapper<TContext> : IDisposable
    where TContext : ObjectContext
{
    private TContext _context;
    private EntityConnectionManager _manager;
    private bool _disposed;

    public ContextWrapper()
        : this(true)
    {
    }

    public ContextWrapper(bool lazyLoadingEnabled)
    {
        _disposed = false;
        _manager = new EntityConnectionManager();
        _context = (TContext)Activator.CreateInstance(typeof(TContext), _manager.Connection);  
        _context.ContextOptions.LazyLoadingEnabled = lazyLoadingEnabled;
    }

    ~ContextWrapper()
    {
        Dispose(false);
    }

    public TContext Context
    {
        get { return _context; }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);

    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                if (_manager != null)
                {
                    _manager.Dispose();
                    _manager = null;
                }
                var ctx = _context as IDisposable;
                if (ctx != null)
                {
                    ctx.Dispose();
                    _context = null;
                }
            }
        }
        _disposed = true;
    }
}

You can see the usage of custom class named EntityConnectionManager:

internal class EntityConnectionManager : IDisposable
{
    private DbConnection _connection;
    private EntityConnection _entityConnection;

    private volatile bool _disposed;

    public EntityConnectionManager()
    {
        var workspace = new MetadataWorkspace(Setting.MetadataWorkspacePaths.Split('|'), new[] { Assembly.ReflectionOnlyLoad(Setting.MetadataAssemblyNameToConsider) });

        _connection = new SqlConnection(Setting.ConnectionString);
        _entityConnection = new EntityConnection(workspace, _connection);
        _disposed = false;
    }

    public EntityConnection Connection
    {
        get { return _entityConnection; }
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_disposed)
        {
            if (disposing)
            {
                if (_connection != null)
                {
                    _connection.Dispose();
                    _connection = null;
                }
                if (_entityConnection != null)
                {
                    _entityConnection.Dispose();
                    _entityConnection = null;
                }
            }
        }
        _disposed = true;
    }
}

So now you can have one connection string:

<connectionStrings>
  <add name="ApplicationServices" connectionString="data source=localhost;user id=user;pwd=pass;initial catalog=VNK;Pooling=False;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />    
</connectionStrings>

and metadata defined in app settings section (the second key points to assembly where your domain model is actually stored):

<appSettings>
  <add key="MetadataWorkspacePaths" value="res://*/VNKModel.csdl|res://*/VNKModel.ssdl|res://*/VNKModel.msl" />
  <add key="MetadataAssemblyNameToConsider" value="VNK.Models" />
</appSettings>

The logic for type Setting is straightforward, as it just pulls out the settings from configuration file.

好久不见√ 2024-10-01 14:31:22

尽管您可以在代码中创建连接,正如 @gandjustas 指出的 (+1),但您无法摆脱连接字符串或 EntityConnection 的束缚。

这是因为它实际上并不是多余的。是的,数据库连接部分是多余的,@gandjustas 向您展示了如何删除该冗余。但是,实体框架连接字符串还包含有关您的模型的信息,这些信息在您希望保留的连接字符串中的任何位置都找不到。该模型信息必须来自某个地方。如果您消除实体框架的连接字符串并使用 ObjectContext 上的参数列表构造函数,您将消除对模型的所有引用。

Although you can create the connection in code, as @gandjustas points out (+1), you cannot get away from having a connection string or EntityConnection.

This is because it is not actually redundant. Yes, the database connection part is redundant, and @gandjustas showed you how to remove that redundancy. However, the entity framework connection string also contains information about your model, which is not found anywhere in the connection string you wish to keep. This model information has to come from somewhere. Were you to eliminate the entity framework's connection string and use the parameter list constructor on ObjectContext, you would have eliminated all references to the model.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文