本文介绍了来自WCF数据服务的Entity Framework 6数据上下文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我曾经使用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数据上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 01:14