我需要将一个Context对象从EF传递给WCF方法。
通常,我在WCF方法中创建Context对象并在方法调用结束之前处理它,这对我的大多数方法都很好。
但是,我需要将Context对象(特别是DBContext)从MVC控制器传递到我的特定WCF方法,因为我为某些查找表启用了缓存。我需要传递这个特定的Context对象(我在Global.asax文件的Application_Start方法中设置的对象),而不是我在上面的句子中所做的,因为我将此特定对象用于SqlDependency。如果我尝试创建全新的DBContext对象,我不能使用SqlDependency,因为我会收到错误通知我在数据库调用之前需要启用SqlDependency。
问题是当我尝试启动我的WCF测试客户端工具时,我遇到了以下错误(简洁起见),我知道这与未正确声明KnownType属性(即DBContext对象)有关。请注意,WCF项目编译得很好。我需要一些特定部分的帮助,因为我从未在WCF服务中使用过KnownType。它们都是简单的类型(int,string等)。
错误:无法从http://localhost:8732/Design_Time_Addresses/YeagerTechWcfService/YeagerTechWcfService/mex
获取元数据如果这是您的Windows(R)Communication Foundation服务 有权访问,请检查您是否已启用元数据发布 指定的地址。有关启用元数据发布的帮助,请 请参阅MSDN文档 http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata交换
错误URI: http://localhost:8732/Design_Time_Addresses/YeagerTechWcfService/YeagerTechWcfService/mex 元数据包含无法解析的引用:
我的WCF服务中有以下OperationContract代码:
[OperationContract]
IEnumerable<Category> GetCategories(YeagerTechEntities DbContext);
我的WCF服务中有以下DataContract代码:
namespace YeagerTechModel
{
[Serializable]
[DataContract(IsReference = true)]
[KnownType(typeof(YeagerTechEntities))]
public partial class Category
{
public Category()
{
this.Projects = new HashSet<Project>();
}
[DataMember]
public short CategoryID { get; set; }
[DataMember]
public string Description { get; set; }
[DataMember]
public virtual ICollection<Project> Projects { get; set; }
}
}
最后,以下是我的WCF方法:
public IEnumerable<YeagerTechModel.Category> GetCategories(YeagerTechEntities DbContext)
{
//YeagerTechEntities DbContext = new YeagerTechEntities();
DbContext.Configuration.ProxyCreationEnabled = false;
IEnumerable<YeagerTechModel.Category> category = DbContext.Categories.Where(p => p.CategoryID > 0).AsCached("Categories").ToList();
//IEnumerable<YeagerTechModel.Category> category = DbContext.Categories.Where(p => p.CategoryID > 0);
CloseConnection(DbContext);
return category;
}
答案 0 :(得分:1)
您需要在注册表/服务定位器模式之后使用单个对象。此对象将保留对全局对象的引用。例如,在应用程序启动时,您将使用SqlDependency
使用您的上下文填充此对象,并且您将使用注册表在控制器的操作和服务操作中访问此上下文。
无论如何都非常谨慎地使用它。 SqlDependency
和EF不能很好地融合在一起,因为它会使你的语境长久存在。长期生活环境为in most cases anti-pattern。除了加载缓存数据之外,永远不要使用该上下文。不要将它用于数据修改或加载非缓存关系!在第一个查询中将实体加载为非跟踪(AsNoTracking
查询扩展方法),并关闭该上下文的代理创建和延迟加载。
另请注意,EF中的查询始终在数据库中执行。我不确定你的AsCached
应该做什么,但我不知道它会起作用。你需要的可能是:
var category = DbContext.Categories.Local
.Where(p => p.CategoryID > 0)
.ToList();
我不会将SqlDependency
用于EF。我会直接使用ADO.NET和SQL。对于EF中的缓存,我会检查EF Caching provider以使用二级缓存,这在大多数情况下都足够了。