0

次の拡張機能はEF6alpha2で機能しますが、null参照例外を使用してalpha3での機能を停止しました。失敗するステートメントはEdmxWriter.WriteEdmx(..)です

ビューの事前生成は、コードファーストのコンテキストで実行されます。

EF6 alpha3を使用して事前生成ビューを実現するにはどうすればよいですか?

 public static PreGeneratedViews PreGenerateViews<T>(this T dbContext) where T : DbContext
    {
        Trace.TraceInformation("PreGenerating views");

        //define ef collections
        EdmItemCollection edmItemCollection = null;
        StoreItemCollection storeItemCollection = null;
        StorageMappingItemCollection mappingItemCollection = null;

        //get ef collections
        GetItemCollections(
            GetEdmx(dbContext),
            out edmItemCollection,
            out storeItemCollection,
            out mappingItemCollection);

        IList<EdmSchemaError> errors = null;
        //get the generated views
        Dictionary<string, string> extentViews = GetExtentViews(mappingItemCollection, out errors);


        //return the pregenerated views as string (xml document)
        return new PreGeneratedViews
                   {
                       EdmEntityContainerName = edmItemCollection.GetItems<EntityContainer>().Single().Name,
                       StoreEntityContainerName = storeItemCollection.GetItems<EntityContainer>().Single().Name,
                       HashOverMappingClosure =
                           ReflectionHelper.GetMappingClosureHash(edmItemCollection.EdmVersion,
                                                                  mappingItemCollection),
                       HashOverAllExtentViews =
                           ReflectionHelper.GenerateHashForAllExtentViewsContent(edmItemCollection.EdmVersion,
                                                                                 extentViews),
                       ViewCount = extentViews.Count,
                       Views = CreateViews(extentViews),
                       ViewsEmbeddedResourceName =
                           string.Format("DbContextViews{0}.xml", Guid.NewGuid().ToString("N")),
                   };
    }

    private static XDocument GetEdmx(DbContext dbContext)
    {
        var ms = new MemoryStream();

        using (XmlWriter writer = XmlWriter.Create(ms))
        {
            EdmxWriter.WriteEdmx(dbContext, writer);
        }

        ms.Position = 0;

        return XDocument.Load(ms);
    }

    private static void SplitEdmx(XDocument edmx, out XmlReader csdlReader, out XmlReader ssdlReader,
                                  out XmlReader mslReader)
    {
        // xml namespace agnostic to make it work with any version of Entity Framework
        XNamespace edmxNs = edmx.Root.Name.Namespace;

        XElement storageModels = edmx.Descendants(edmxNs + "StorageModels").Single();
        XElement conceptualModels = edmx.Descendants(edmxNs + "ConceptualModels").Single();
        XElement mappings = edmx.Descendants(edmxNs + "Mappings").Single();

        ssdlReader = storageModels.Elements().Single(e => e.Name.LocalName == "Schema").CreateReader();
        csdlReader = conceptualModels.Elements().Single(e => e.Name.LocalName == "Schema").CreateReader();
        mslReader = mappings.Elements().Single(e => e.Name.LocalName == "Mapping").CreateReader();
    }

    private static void GetItemCollections(XDocument edmx, out EdmItemCollection edmItemCollection,
                                           out StoreItemCollection storeItemCollection,
                                           out StorageMappingItemCollection mappingItemCollection)
    {
        // extract csdl, ssdl and msl artifacts from the Edmx
        XmlReader csdlReader, ssdlReader, mslReader;
        SplitEdmx(edmx, out csdlReader, out ssdlReader, out mslReader);

        // Initialize item collections
        edmItemCollection = new EdmItemCollection(new[] {csdlReader});
        storeItemCollection = new StoreItemCollection(new[] {ssdlReader});
        mappingItemCollection = new StorageMappingItemCollection(edmItemCollection, storeItemCollection,
                                                                 new[] {mslReader});
    }

    private static Dictionary<string, string> GetExtentViews(StorageMappingItemCollection mappingItemCollection,
                                                             out IList<EdmSchemaError> errors)
    {
        Dictionary<EntitySetBase, string> views = ReflectionHelper.GenerateViews(mappingItemCollection, out errors);
        if (errors != null && errors.Any())
        {
            return null;
        }

        var extentViews = new Dictionary<string, string>(views.Count);

        foreach (var kvp in views)
        {
            extentViews.Add(
                GetExtentFullName(kvp.Key),
                kvp.Value.Replace("\r\n", "\n")); // replace accounts for Xml new line normalization
        }

        return extentViews;
    }

    private static string GetExtentFullName(EntitySetBase entitySet)
    {
        return string.Format("{0}.{1}", entitySet.EntityContainer.Name, entitySet.Name);
    }


    private static string CreateViews(Dictionary<string, string> extentViews)
    {
        var sb = new StringBuilder();
        //var embeddedViewsFileName = Path.ChangeExtension(Host.TemplateFile, "xml");
        using (XmlWriter writer = XmlWriter.Create(sb, new XmlWriterSettings
                                                           {
                                                               Indent = true,
                                                               Encoding = Encoding.UTF8
                                                           }))
        {
            writer.WriteStartElement("views");
            foreach (var kvp in extentViews)
            {
                writer.WriteStartElement("view");
                writer.WriteAttributeString("extent", kvp.Key);
                writer.WriteCData(kvp.Value);
                writer.WriteEndElement();
            }

            writer.WriteEndElement();
        }

        return sb.ToString();
    }

    #region Nested type: ReflectionHelper

    private static class ReflectionHelper
    {
        private static readonly Assembly efAssembly = typeof (StorageMappingItemCollection).Assembly;

        private static readonly MethodInfo generateViewsMethodInfo =
            typeof (StorageMappingItemCollection).GetMethod("GenerateEntitySetViews",
                                                            BindingFlags.NonPublic | BindingFlags.Instance);

        private static readonly MethodInfo getMappingClosureHashMethodInfo =
            efAssembly.GetType("System.Data.Entity.Core.Mapping.MetadataMappingHasherVisitor", true)
                .GetMethod("GetMappingClosureHash", BindingFlags.Static | BindingFlags.NonPublic);

        private static readonly MethodInfo generateHashForAllExtentViewsContentMethodInfo =
            efAssembly.GetType("System.Data.Entity.Core.Common.Utils.MetadataHelper", true)
                .GetMethod("GenerateHashForAllExtentViewsContent", BindingFlags.Static | BindingFlags.NonPublic);

        public static Dictionary<EntitySetBase, string> GenerateViews(
            StorageMappingItemCollection mappingItemCollection, out IList<EdmSchemaError> errors)
        {
            errors = null;
            return
                (Dictionary<EntitySetBase, string>)
                generateViewsMethodInfo.Invoke(mappingItemCollection, new object[] {errors});
        }

        public static string GetMappingClosureHash(double schemaVersion,
                                                   StorageMappingItemCollection mappingItemCollection)
        {
            return (string) getMappingClosureHashMethodInfo.Invoke(
                null,
                new object[]
                    {
                        schemaVersion, 
                        // CodeFirst currently creates always one entity container
                        mappingItemCollection.GetItems<GlobalItem>().Single(
                            i => i.GetType().Name == "StorageEntityContainerMapping")
                    });
        }

        public static string GenerateHashForAllExtentViewsContent(double schemaVersion,
                                                                  Dictionary<string, string> extentViews)
        {
            return (string) generateHashForAllExtentViewsContentMethodInfo.Invoke(
                null,
                new object[] {schemaVersion, extentViews});
        }
    }

スタックトレースは次のとおりです。

NullReferenceException

  • で:System.Data.Entity.Edm.Serialization.EdmSerializationVisitor.VisitEdmAssociationSet(AssociationSet item)
  • at:System.Data.Entity.Edm.EdmModelVisitor.VisitCollection [T](IEnumerable 1 collection, Action1 visitMethod)
  • at:System.Data.Entity.Edm.EdmModelVisitor.VisitAssociationSets(EntityContainer container、IEnumerable`1associationSets)
  • で:System.Data.Entity.Edm.EdmModelVisitor.VisitEdmEntityContainer(EntityContainer item)
  • で:System.Data.Entity.Edm.Serialization.EdmSerializationVisitor.VisitEdmEntityContainer(EntityContainer item)
  • at:System.Data.Entity.Edm.EdmModelVisitor.VisitCollection [T](IEnumerable 1 collection, Action1 visitMethod)
  • で:System.Data.Entity.Edm.EdmModelVisitor.VisitEntityContainers(IEnumerable`1 entityContainers)
  • で:System.Data.Entity.Edm.EdmModelVisitor.VisitEdmModel(EdmModel item)
  • で:System.Data.Entity.Edm.Serialization.EdmSerializationVisitor.Visit(EdmModel edmModel、文字列namespaceName、文字列プロバイダー、文字列providerManifestToken)
  • で:System.Data.Entity.Edm.Serialization.EdmSerializationVisitor.Visit(EdmModel edmModel、文字列プロバイダー、文字列プロバイダーManifestToken)
  • at:System.Data.Entity.Edm.Serialization.SsdlSerializer.Serialize(EdmModel dbDatabase、文字列プロバイダー、文字列プロバイダーManifestToken、XmlWriter xmlWriter、ブール値serializeDefaultNullability)
  • で:System.Data.Entity.ModelConfiguration.Edm.Serialization.EdmxSerializer.WriteEdmxRuntime()
  • で:System.Data.Entity.ModelConfiguration.Edm.Serialization.EdmxSerializer.Serialize(DbDatabaseMapping databaseMapping、DbProviderInfo ProviderInfo、XmlWriter xmlWriter)
  • で:System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbModelモデル、XmlWriterライター)
  • で:System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbContextコンテキスト、XmlWriterライター)
  • で:** .DbContextPreGenerateViewExtension.GetEdmx(DbContext dbContext)

ありがとう!

4

2 に答える 2

1

作業項目867 (35852e8392ad) の修正を送信しました。NREを修正する必要があります。この修正は、今日のナイトリー ビルドに含まれているはずです。試してみて、これで問題が解決したかどうかをお知らせください。

于 2013-03-05T23:18:29.187 に答える
0

これはAlpha3の既知のバグです。

于 2013-03-04T17:20:14.557 に答える