问题描述
我曾经使用this.CurrentDataSource.MyEntity
从wcf数据服务服务内部访问(ef 5.0)实体的数据上下文.我的数据服务继承自DataService<T>
.现在,我想使用实体框架6.0并在Internet上阅读,我应该从EntityFrameworkDataService<T>
继承服务.但是现在从服务操作内部,我无法再访问数据上下文. this.CurrentDataSource
不包含对实体的任何引用.
I used to access the data context of my (ef 5.0) entities from inside a wcf data services service operation with this.CurrentDataSource.MyEntity
.My data service inherited from DataService<T>
. Now I wanted to use entity framework 6.0 and read on the internet, I should inherit the service from EntityFrameworkDataService<T>
. But now from inside my service operations, I cannot access my data context anymore. this.CurrentDataSource
doesn't contain any reference to the entities.
推荐答案
这是我使用扩展方法的变通办法,该方法通过(缓存的)反射信息获取基础数据模型.它适用于当前的Microsoft.OData.EntityFrameworkProvider版本1.0.0 alpha 2.
Here's my workaround using an extension method that gets the underlying data model via (cached) reflection info. It works for the current Microsoft.OData.EntityFrameworkProvider version 1.0.0 alpha 2.
示例用法用于自定义WebGet方法:
Sample usage is for a custom WebGet method:
[WebGet]
public string GetMyEntityName(string myEntityKey)
{
var model = this.CurrentDataSource.GetDataModel();
var entity = model.MyEntity.Find(myEntityKey);
return entity.Name;
}
实施:
public static class EntityFrameworkDataServiceProvider2Extensions
{
/// <summary>
/// Gets the underlying data model currently used by an EntityFrameworkDataServiceProvider2.
/// </summary>
/// <remarks>
/// TODO: Obsolete this method if the API changes to support access to the model.
/// Reflection is used as a workaround because EntityFrameworkDataServiceProvider2 doesn't (yet) provide access to its underlying data source.
/// </remarks>
public static T GetDataModel<T>(this EntityFrameworkDataServiceProvider2<T> efProvider) where T : class
{
if (efProvider != null)
{
Type modelType = typeof(T);
// Get the innerProvider field info for an EntityFrameworkDataServiceProvider2 of the requested type
FieldInfo ipField;
if (!InnerProviderFieldInfoCache.TryGetValue(modelType, out ipField))
{
ipField = efProvider.GetType().GetField("innerProvider", BindingFlags.NonPublic | BindingFlags.Instance);
InnerProviderFieldInfoCache.Add(modelType, ipField);
}
var innerProvider = ipField.GetValue(efProvider);
if (innerProvider != null)
{
// Get the CurrentDataSource property of the innerProvider
PropertyInfo cdsProperty;
if (!CurrentDataSourcePropertyInfoCache.TryGetValue(modelType, out cdsProperty))
{
cdsProperty = innerProvider.GetType().GetProperty("CurrentDataSource");
CurrentDataSourcePropertyInfoCache.Add(modelType, cdsProperty);
}
return cdsProperty.GetValue(innerProvider, null) as T;
}
}
return null;
}
private static readonly ConditionalWeakTable<Type, FieldInfo> InnerProviderFieldInfoCache = new ConditionalWeakTable<Type, FieldInfo>();
private static readonly ConditionalWeakTable<Type, PropertyInfo> CurrentDataSourcePropertyInfoCache = new ConditionalWeakTable<Type, PropertyInfo>();
}
System.Runtime.CompilerServices.ConditionalWeakTable 用于缓存反射结果基于来自缓存反射数据
System.Runtime.CompilerServices.ConditionalWeakTable was used to cache reflection results based on a suggestion taken from Caching reflection data
这篇关于来自WCF数据服务的Entity Framework 6数据上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!