Строка подключения не найдена, но только во время разработки

Привет, я довольно новичок в WPF и C#, поэтому, пожалуйста, будьте осторожны, если это просто глупый вопрос:

Я использую VS2012, Entity Framework для создания модели существующей базы данных, и я хотел бы связать некоторые таблицы с некоторым ListView... Теперь я знаю, что есть разные способы сделать это, но когда я пытаюсь использовать ObjectDataProvider Я получаю сообщение об ошибке во время разработки: "Не найдена строка подключения... Не удалось найти файл конфигурации приложения".

Странно то, что если я запускаю свое приложение, все работает как надо, я просто хотел бы удалить это уродливое сообщение об ошибке и, надеюсь, получить данные во время разработки моего списка объявлений (поэтому я хотел бы использовать объектный провайдер).

Вот некоторые части моего кода:

App.Config:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <connectionStrings>
    <add name="BibliotecaEntities" 
         connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;provider=System.Data.SqlClient;provider connection string='data source=(LocalDB)\v11.0;attachdbfilename=&quot;G:\PROGETTI-SOFTWARE\c# tests\Biblioteca\Biblioteca\biblioteca-db.mdf&quot;;initial catalog=BibliotecaDB;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework'" 
         providerName="System.Data.EntityClient" />
  </connectionStrings>
</configuration>

ListaScaffali.xaml:

<Window x:Class="Biblioteca.ShelvesList"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Biblioteca;assembly=" 
        Title="ShelvesList" Height="341" Width="609">

    <Window.Resources>
        <ObjectDataProvider ObjectType="{x:Type local:BooksDB_Handler}" MethodName="TuttiGliScaffali" x:Key="ScaffaliObjSrc" />
    </Window.Resources>

    <Grid>
        <Grid>
            <ListView Name="listaScaffali" ItemsSource="{Binding Source={StaticResource ScaffaliObjSrc}}">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="Scaffali Disponibili:" DisplayMemberBinding="{Binding Scaffale}" />
                    </GridView>
                </ListView.View>
            </ListView>
        </Grid>
    </Grid>
</Window>

BooksDB-Handler.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using System.Data.Entity;
using System.Collections.ObjectModel;

namespace Biblioteca
{
    public static class BooksDB_Handler
    {

    ...

        public static ObservableCollection<Scaffali> TuttiGliScaffali()
        {
            using (var ctx = new BibliotecaEntities())
            {

                var reader = from d in ctx.Scaffali
                             select d;
                return new ObservableCollection<Scaffali>(reader);
            }
        }

    ...

    }
}

В моей БД таблица "Scaffali" имеет только две колонки: "ScaffaliID" (идентификатор) и "Scaffale".

Я где-то читал, что это может быть ошибка Visual Studio, и пробовал разные вещи:

  1. восстановить несколько раз
  2. избегать # в путях
  3. скомпилировать для 32 бит (я использую Win8 x64)

но до сих пор не повезло...

Спасибо за ваш добрый ответ.

- = ОБНОВЛЕНИЕ 04/03/2013 =-

До сих пор я до сих пор не нашел, каковы условия, вызывающие это странное поведение, так или иначе, я обнаружил, что, если я просто собираю (не перестраиваю) два раза подряд, сообщение об ошибке просто исчезает, и кажется, что все работает как надо...

3 ответа

У меня была та же проблема, и я обнаружил, что во время разработки IDE, похоже, не читает App.config, чтобы получить строку соединения, поэтому она разрывается при установлении соединения. В итоге я проверил, находится ли код во время разработки, и вручную создал несколько элементов для целей проектирования.

Я использую следующий код, чтобы узнать, находится ли среда в режиме разработки:

public static bool IsInDesignMode
{
    get
    {
        #if Silverlight
            return !HtmlPage.IsEnabled;;
        #else
            return DesignerProperties.GetIsInDesignMode(new DependencyObject());
        #endif
    }
}

Затем в своем коде, куда я возвращаю предметы, я делаю следующее:

if (IsInDesignMode)
{
    GetSampleData();
}
else
{
    GetQueryData();
}

И я просто реализую эти два метода.

Может быть, есть лучшее решение, но у меня это сработало.

Это решение выглядело многообещающе, но мне еще предстоит заставить его работать на меня...

Источник: http://developernote.com/2012/03/rich-design-time-experience-with-wpf-and-ef-in-visual-studio-2010/

Иногда способность видеть данные во время разработки значительно облегчает создание элементов управления WPF. Если я разрабатываю элемент управления WPF со сложным пользовательским интерфейсом с использованием элементов управления с привязкой к данным, я обычно определяю свойство для доступа к некоторому типичному элементу данных:

public static ComplexData DesignTimeItem
{
    get
    {
        using (DatabaseContext db = new DatabaseContext())
        {
            var products = from p in db.products.Include("ProductType")
                           where p.product_id == 131
                           select p;

            product product = products.First();

            return new ComplexData(product, "100 kg");
        }
    }
}

и затем я использую это свойство непосредственно в XAML во время разработки:

<UserControl x:Class="SomeControl"
    ...
    xmlns:local="clr-namespace:ControlNamespace"
    DataContext="{Binding Source={x:Static local:ComplexData.DesignTimeItem}, Mode=OneWay}"
    ...
>

Тогда мне нужно сделать последний шаг. Проблема заключается в том, что конструктор контекста сущности по умолчанию (DatabaseContext) использует строку подключения, включенную в файл конфигурации приложения во время выполнения app.config:

<connectionStrings>
  <add name="MyContext" connectionString="metadata=res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyModel.msl;provider=MySql.Data.MySqlClient;provider connection string=&quot;password=******;User Id=myuser;server=myserver;database=mydb;Persist Security Info=True;charset=utf8&quot;" providerName="System.Data.EntityClient"/>
</connectionStrings>

но во время разработки файл конфигурации приложения - devenv.exe.config, который не содержит строку подключения, и поэтому создание моего элемента управления WPF завершается неудачно, в результате чего дизайнер не загружается. Чтобы решить эту проблему, я просто скопирую строку подключения, включенную в app.config, в файл devenv.exe.config, расположенный в папке "C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\", и перезапускаю Visual Studio.

Вы пытались создать объект DataContext с ConnectionString самостоятельно, вместо того, чтобы позволить платформе использовать тот, который указан в файле конфигурации? Я обычно предпочитаю создавать этот объект самостоятельно, поэтому я могу легко переместить его в другую сборку и внедрить зависимость соединения. Но это уже другая история. В вашем случае, я бы порекомендовал вам попробовать эти вещи:

  1. Сохраните строку подключения в webconfig.
  2. Создайте контекст самостоятельно

    var connectionStringBuilder = new EntityConnectionStringBuilder { Metadata = "{metadata}", Provider = "{provider}", ProviderConnectionString = "{строка подключения из конфигурации}"};

    var ctx = new BibliotecaEntities (connectionStringBuilder.ToString ());

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

Другие вопросы по тегам