Чтение конфигурационного файла из расширения оболочки - PullRequest
0 голосов
/ 03 июля 2019

У меня есть проект, который настроен как расширение оболочки с библиотекой SharpShell. Когда я регистрирую его с помощью инструмента regasm (с включенным флагом /codebase), он работает до того момента, когда мне нужно использовать базу данных через EntityNetwork. Я получаю эту ошибку:

Не удалось найти строку подключения с именем EntitiesName в файл конфигурации приложения.

Но, конечно, у меня есть правильный ConnectionString в файле config. Похоже, что весь файл config вообще не читается.

Итак, я нашел какое-то хакерское решение и поместил его в конструктор:

    Dim assemblyLoc As String = [GetType].Assembly.Location
    Dim configName As String = assemblyLoc + ".config"
    AppDomain.CurrentDomain.SetData("APP_CONFIG_FILE", configName)

и кажется, что что-то прочитано, но не все, я получаю новую ошибку:

System.TypeInitializationException: инициализатор типа для 'System.Data.Entity.Internal.AppConfig' вызвал исключение. ---> System.Configuration.ConfigurationErrorsException: произошла ошибка при создании обработчика раздела конфигурации для entityFramework: не удалось загрузить файл или сборку 'EntityFramework, Version = 6.0.0.0, Culture = нейтральный, PublicKeyToken = b77a5c561934e089' или одну из его зависимостей. Система не может найти указанный файл.

Как я могу использовать файл конфигурации или как EntityFramework с такими настройками?

Вот так выглядит мой config файл:

    <?xml version="1.0" encoding="utf-8"?>
    <configuration>
      <configSections>
        <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
        <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
      </configSections>
      <connectionStrings>
        <add name="EntitiesName" connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string=&quot;***&quot;" providerName="System.Data.EntityClient" />
      </connectionStrings>
      <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
      </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>
    </configuration>

Я подозреваю, что мне может понадобиться Конфигурация на основе кода . Если это так, я бы оценил несколько vb.net указателей в этом направлении.

1 Ответ

0 голосов
/ 04 июля 2019

После двух дней или около того яростного поиска какой-то документации (почти не существующей для vb.net и даже для c # всегда чего-то не хватает) я собрал эти два класса:

Imports System.Data.Entity
Imports System.Data.Entity.Core.EntityClient
Imports System.Data.SqlClient

Partial Public Class MyConfig
    Inherits DbConfiguration

    Public Sub New()
        Me.SetProviderServices("System.Data.SqlClient", Entity.SqlServer.SqlProviderServices.Instance)
    End Sub
End Class

Public Class ConnectionStringBuilder
    Public Shared Function Construct() As String
        Dim newConnStringBuilder = New SqlConnectionStringBuilder With {
            .UserID = "user",
            .Password = "pass",
            .InitialCatalog = "database",
            .DataSource = "server"
        }
        Dim entityConnectionBuilder = New EntityConnectionStringBuilder With {
            .Provider = "System.Data.SqlClient",
            .ProviderConnectionString = newConnStringBuilder.ToString(),
            .Metadata = "res://*/Model1.csdl|
                            res://*/Model1.ssdl|
                            res://*/Model1.msl"
        }
        Return entityConnectionBuilder.ToString()
    End Function
End Class

Затем в edmx классе модели (в моем случае Model1.Context.vb) примерно так:

'------------------------------------------------------------------------------
' <auto-generated>
'     This code was generated from a template.
'
'     Manual changes to this file may cause unexpected behavior in your application.
'     Manual changes to this file will be overwritten if the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------

Imports System
Imports System.Data.Entity
Imports System.Data.Entity.Infrastructure

<DbConfigurationType(GetType(MyConfig))>
Partial Public Class MyEntities
    Inherits DbContext

    Public Sub New()
        MyBase.New(ConnectionStringBuilder.Construct())
        'MyBase.New("name=MyEntities")
    End Sub

    Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
        Throw New UnintentionalCodeFirstException()
    End Sub

    Public Overridable Property XXXs() As DbSet(Of XXX)
    'etc...

End Class

Я уверен, что может быть лучший подход, но пока это лучшее, что у меня есть, и я публикую его здесь, чтобы потенциально помочь и / или продолжить обсуждение / исправление.

...