2014-01-09 3 views
3

Есть ли способ создать DbContext без фактического подключения к базе данных?Создание DbContext без подключения к базе данных

Я хочу, чтобы иметь возможность получить доступ к СКТ и метаданные SSDL, например, так:

var objContext = ((IObjectContextAdapter)myDbContext).ObjectContext; 
var ssdl = objContext.MetadataWorkspace.GetItemCollection(DataSpace.SSpace); 
var csdl = objContext.MetadataWorkspace.GetItemCollection(DataSpace.CSpace); 

, но я не хочу, чтобы получить доступ к базе данных на всех. В идеале я хотел бы иметь доступ к метаданным SSDL/CSDL, даже не имея базы данных.

+0

Вы можете, когда у вас есть файл EDMX см http://stackoverflow.com/a/ 36357185/1860652 - не знаю о первом коде – AlexFoxGill

+0

Если бы у меня был файл EDMX, я мог бы просто читать CSDL/SSDL, не имея DbContext. Интересная ссылка, хотя, спасибо. –

+0

Проверьте весь ответ - вы можете создать EDMX в памяти с помощью EdmxWriter, а затем обработать это. Это займет некоторое время, но это выполнимо! – AlexFoxGill

ответ

1

dbContext - это абстракция над базой данных. Если нет базы данных, то абстракции нет. Вы можете создать DbContext без подключения к базе данных. Если установить инициализатор базы данных нулевое значение для контекста тогда Code First никогда не будет пытаться создать базу данных для вас:

DbDatabase.SetInitializer<MyContext>(null); 

Но это не полезно в вашем случае

+1

Есть ли способ получить метаданные без DbContext/ObjectContext и базы данных? –

0

См this answer на аналогичный вопрос (упрощенный код ниже) - это работает только для Code First (версия EDMX находится в связанном ответе). Ключом является создание контекста с использованием строки подключения «App = EntityFramework».

public static MetadataWorkspace GetMetadataWorkspaceFromCodeFirst<TContext>(Func<string, TContext> createFromConnectionString) where TContext : DbContext 
{ 
    using (var ctx = createFromConnectionString("App=EntityFramework")) 
    using (var ms = new MemoryStream()) 
    using (var writer = new XmlTextWriter(ms, Encoding.UTF8)) 
    { 
     EdmxWriter.WriteEdmx(ctx, writer); 
     ms.Seek(0, SeekOrigin.Begin); 
     var xDoc = XDocument.Load(ms); 
     var runtime = xDoc.Root.Elements().First(c => c.Name.LocalName == "Runtime"); 
     var cSpaceLoader = new EdmItemCollection(GetXmlReader(runtime, "ConceptualModels")); 
     var sSpaceLoader = new StoreItemCollection(GetXmlReader(runtime, "StorageModels")); 
     var mSpaceLoader = new StorageMappingItemCollection(cSpaceLoader, sSpaceLoader, 
      GetXmlReader(runtime, "Mappings")); 
     return new MetadataWorkspace(() => cSpaceLoader,() => sSpaceLoader,() => mSpaceLoader); 
    } 
} 

private static IEnumerable<XmlReader> GetXmlReader(XContainer runtimeElement, string elementName) 
{ 
    var model = runtimeElement.Elements().First(c => c.Name.LocalName == elementName).Elements().First(); 
    yield return XmlReader.Create(new StringReader(model.ToString())); 
} 

Требуется, что ваш DbContext имеет конструктор с одним параметром, который string вы передаете в качестве делегата в вызове

Смежные вопросы