Исключение EFContextProvider только для метаданных Breeze

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

Я написал модульный тест для инкапсуляции функциональности в простой интерфейс с именем IMetadataProvider, который просто имеет свойство get only string для возврата метаданных из EFContextProvider.

В основном в примерах будет показан DbContext, внедренный в контроллер(ы) WebApi, и для нашей реализации это не сработает. Наши контроллеры Web-Api-2 размещаются в отдельном проекте от основного веб-сайта и дополнительно имеют реализацию Uow/Repository, предоставленную другой командой разработчиков. Введите абстракцию.

Что я упустил из виду?

/// Implementation of Common Contract Interface
namespace SMB.Client.Metadata
{
    #region Usings
    using Breeze.ContextProvider.EF6;
    using SMB.Core.Contracts;

    #endregion

    public class ClientMetadataProvider : IMetadataProvider
    {
        public string Metadata
        {
            get
            {
                EFContextProvider<ClientMetadataDbContext> breezeContextProvider =
                    new EFContextProvider<ClientMetadataDbContext>();

                return breezeContextProvider.Metadata();
            }
        }
    }
}

/// Unit Test

namespace SMB.Client.Metadata.Tests
{
    #region Usings
    using Microsoft.VisualStudio.TestTools.UnitTesting;
    using SMB.Core.Contracts;

    #endregion

    [TestClass]
    public class ClientMetadataProviderTests
    {
        IMetadataProvider TheMetadataProvider;

        [TestInitialize]
        public void Initialize()
        {
            this.TheMetadataProvider =
                new ClientMetadataProvider();
        }

        [TestMethod]
        public void ClientMetadataProviderTests_MetadataPropertyIsNotEmpty()
        {
            string theActualMetadata =
                this.TheMetadataProvider
                    .Metadata;

            Assert.IsFalse(string.IsNullOrEmpty(theActualMetadata));
        }
    }
}

Я получаю следующее исключение

Test Name:  ClientMetadataProviderTests_MetadataPropertyIsNotEmpty
Test FullName:  SMB.Client.Metadata.Tests.ClientMetadataProviderTests.ClientMetadataProviderTests_MetadataPropertyIsNotEmpty
Test Source:    c:\all\tfs\Main\Source\SMB\Tests\SMB.Client.Metadata.Tests\ClientMetadataProviderTests.cs : line 24
Test Outcome:   Failed
Test Duration:  0:01:06.5845416

Result Message: 
Test method SMB.Client.Metadata.Tests.ClientMetadataProviderTests.ClientMetadataProviderTests_MetadataPropertyIsNotEmpty threw exception: 
System.NullReferenceException: Object reference not set to an instance of an object.
Result StackTrace:  
at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
   at System.Data.Entity.Internal.LazyInternalContext.get_ModelBeingInitialized()
   at System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbContext context, XmlWriter writer)
   at Breeze.ContextProvider.EF6.EFContextProvider`1.GetMetadataFromDbContext(Object context)
   at Breeze.ContextProvider.EF6.EFContextProvider`1.GetMetadataFromContext(Object context)
   at Breeze.ContextProvider.EF6.EFContextProvider`1.BuildJsonMetadata()
   at Breeze.ContextProvider.ContextProvider.Metadata()
   at SMB.Client.Metadata.ClientMetadataProvider.get_Metadata() in c:\all\tfs\Main\Source\SMB\Client\SMB.Client.Metadata\ClientMetadataProvider.cs:line 19
   at SMB.Client.Metadata.Tests.ClientMetadataProviderTests.ClientMetadataProviderTests_MetadataPropertyIsNotEmpty() in c:\all\tfs\Main\Source\SMB\Tests\SMB.Client.Metadata.Tests\ClientMetadataProviderTests.cs:line 25

/// Xml App.config [Copied from DocCode sample]

<?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>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="4.5.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

person jjhayter    schedule 19.05.2014    source источник


Ответы (1)


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

Измененный 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>
  <connectionStrings>
    <add name="ClientMetadataDbContext" connectionString="Data Source=.\;Initial Catalog=ClientMetadata;Integrated Security=true;Persist Security Info=true;MultipleActiveResultSets=true;" providerName="System.Data.SqlClient" />
  </connectionStrings>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" />
    <providers>
      <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
    </providers>
  </entityFramework>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="4.5.0.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>

Покопавшись в образце DocCode, я нашел этот комментарий в файле web.config и ответил бы, что да, он вам понадобится.

<!-- TODO: is this needed?
     phony FoosMetadataContext connection enables FoosMetadataProvider to succeed; there is no nonsense.sdf-->
<add name="FoosMetadataContext" connectionString="Data Source=|DataDirectory|nonsense.sdf" providerName="System.Data.SqlServerCe.4.0" />
person jjhayter    schedule 19.05.2014