sono stato in grado di convertire la soluzione da Jan Matousek a lavorare in vb.net 2013, con Entity Framework 6. Cercherò anche di spiegare come utilizzare il codice in vb.net.
Abbiamo un database JD Edwards che utilizza diversi schemi per ogni ambiente (TESTDTA, CRPDTA, PRODDTA). Ciò rende difficile il passaggio da un ambiente all'altro, in quanto è necessario modificare manualmente il file .edmx se si desidera modificare gli ambienti.
Il primo passaggio consiste nel creare una classe parziale che consente di passare un valore al costruttore delle entità, per impostazione predefinita utilizza i valori del file di configurazione.
Partial Public Class JDE_Entities
Public Sub New(ByVal myObjectContext As ObjectContext)
MyBase.New(myObjectContext, True)
End Sub
End Class
Quindi creare la funzione che modificherà il file .ssdl dello schema del negozio in memoria.
Public Function CreateObjectContext(ByVal schema As String, ByVal connString As String, ByVal model As String) As ObjectContext
Dim myEntityConnection As EntityConnection = Nothing
Try
Dim conceptualReader As XmlReader = XmlReader.Create(Me.GetType().Assembly.GetManifestResourceStream(model + ".csdl"))
Dim mappingReader As XmlReader = XmlReader.Create(Me.GetType().Assembly.GetManifestResourceStream(model + ".msl"))
Dim storageReader As XmlReader = XmlReader.Create(Me.GetType().Assembly.GetManifestResourceStream(model + ".ssdl"))
Dim storageNS As XNamespace = "http://schemas.microsoft.com/ado/2009/11/edm/ssdl"
Dim storageXml = XDocument.Load(storageReader)
Dim conceptualXml = XDocument.Load(conceptualReader)
Dim mappingXml = XDocument.Load(mappingReader)
For Each myItem As XElement In storageXml.Descendants(storageNS + "EntitySet")
Dim schemaAttribute = myItem.Attributes("Schema").FirstOrDefault
If schemaAttribute IsNot Nothing Then
schemaAttribute.SetValue(schema)
End If
Next
storageXml.Save("storage.ssdl")
conceptualXml.Save("storage.csdl")
mappingXml.Save("storage.msl")
Dim storageCollection As StoreItemCollection = New StoreItemCollection("storage.ssdl")
Dim conceptualCollection As EdmItemCollection = New EdmItemCollection("storage.csdl")
Dim mappingCollection As StorageMappingItemCollection = New StorageMappingItemCollection(conceptualCollection, storageCollection, "storage.msl")
Dim workspace = New MetadataWorkspace()
workspace.RegisterItemCollection(conceptualCollection)
workspace.RegisterItemCollection(storageCollection)
workspace.RegisterItemCollection(mappingCollection)
Dim connectionData = New EntityConnectionStringBuilder(connString)
Dim connection = DbProviderFactories.GetFactory(connectionData.Provider).CreateConnection()
connection.ConnectionString = connectionData.ProviderConnectionString
myEntityConnection = New EntityConnection(workspace, connection)
Return New ObjectContext(myEntityConnection)
Catch ex As Exception
End Try
End Function
Assicurarsi che lo spazio dei nomi valore hardcoded storageNS corrisponde a quello utilizzato nel codice, è possibile visualizzare questo il debug del codice ed esaminando la variabile storageXML per vedere ciò che è stato effettivamente utilizzato.
Ora è possibile passare un nuovo nome schema e diverse informazioni di connessione al database in fase di runtime quando si creano le entità. Non sono necessarie ulteriori modifiche manuali .edmx.
Using Context As New JDE_Entities(CreateObjectContext("NewSchemaNameHere", ConnectionString_EntityFramework("ServerName", "DatabaseName", "UserName", "Password"), "JDE_Model"))
Dim myWO = From a In Context.F4801 Where a.WADOCO = 400100
If myWO IsNot Nothing Then
For Each r In myWO
Me.Label1.Text = r.WADL01
Next
End If
End Using
Queste erano le librerie .NET utilizzati:
Imports System.Data.Entity.Core.EntityClient
Imports System.Xml
Imports System.Data.Common
Imports System.Data.Entity.Core.Metadata.Edm
Imports System.Reflection
Imports System.Data.Entity.Core.Mapping
Imports System.Data.Entity.Core.Objects
Imports System.Data.Linq
Imports System.Xml.Linq
Speranza che aiuta qualcuno là fuori con gli stessi problemi.
Questa soluzione ha funzionato perfettamente per me. Nel mio caso, tutto quello che dovevo fare era passare attraverso i prefissi delle tabelle. Tuttavia, la sintassi per me era leggermente diversa: modelBuilder.Entity() .Map (x => x.ToTable (_tablePrefix + tableName)); Grazie Serg! –
adamisnt
Felice di sentire! La sintassi cambierà, poiché il mio codice è stato scritto e testato su Entity Framework CTP4. – msa7