来自wcf数据服务的实体框架6数据上下文

Mat*_*ias 4 c# entity-framework wcf-data-services objectcontext

我曾经在wcf数据服务服务操作中访问我的(ef 5.0)实体的数据上下文this.CurrentDataSource.MyEntity.我的数据服务继承自DataService<T>.现在我想使用实体框架6.0并在互联网上阅读,我应该继承服务EntityFrameworkDataService<T>.但是现在从我的服务操作中,我再也无法访问我的数据上下文了.this.CurrentDataSource不包含对实体的任何引用.

Dav*_*A-W 8

这是我的解决方法,使用扩展方法通过(缓存)反射信息获取基础数据模型.它适用于当前的Microsoft.OData.EntityFrameworkProvider版本1.0.0 alpha 2.

示例用法适用于自定义WebGet方法:

    [WebGet]
    public string GetMyEntityName(string myEntityKey)
    {
        var model = this.CurrentDataSource.GetDataModel();
        var entity = model.MyEntity.Find(myEntityKey);
        return entity.Name;
    }
Run Code Online (Sandbox Code Playgroud)

并实施:

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>();
}
Run Code Online (Sandbox Code Playgroud)

System.Runtime.CompilerServices.ConditionalWeakTable用于根据缓存反射数据中的建议缓存反射结果