我试图通过WCF从实体框架中检索对象列表,但我收到以下异常:
尝试序列化参数_2573502时出错 . InnerException消息是'Type ' System.Data.Entity.DynamicProxies.TestObject_240F2B681A782799F3A0C3AFBE4A67A7E86083C3CC4A3939573C5410B408ECCE ' with data contract name ' TestObject_240F2B681A782799F3A0C3AFBE4A67A7E86083C3CC4A3939573C5410B408ECCE:http://schemas.datacontract.org/2004/07/System.Data.Entity.DynamicProxies ' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.' . 有关更多详细信息,请参阅InnerException .
我过去使用过WCF,但从未使用过Entity Framework . 我通过Entity Framework生成了所有实体,并使用[DataContract]和[DataMember]属性进行了注释 . 我的任何实体都没有导航属性 .
被调用的GetAll()方法位于抽象服务类中:
[ServiceContract]
public interface IService<T>
{
[OperationContract]
List<T> GetAll();
}
我正在使用ChannelFactory来调用我的实现:
Binding binding = new NetTcpBinding();
EndpointAddress endpointAddress = new EndpointAddress("net.tcp://localhost:8081/" + typeof(TestObjectService).Name);
using (ChannelFactory<ITestObjectService> channel = new ChannelFactory<ITestObjectService>(binding, endpointAddress))
{
ITestObjectService testObjectService = channel.CreateChannel();
testObjects = testObjectService.GetAll();
channel.Close();
}
我这样托管它:
Type type = typeof(TestObjectService);
ServiceHost host = new ServiceHost(type,
new Uri("http://localhost:8080/" + type.Name),
new Uri("net.tcp://localhost:8081/" + type.Name));
host.Open();
使用调试时,它会从数据库中找到对象,但是,它无法返回对象 .
关于我可能出错的地方的任何想法?
5 回答
这很难理解,但这是因为EntityFramework创建了一个类的“代理” . 我正确设置的TestObject类,但它创建了一个名为的类:TestObject_240F2B681A782799F3A0C3AFBE4A67A7E86083C3CC4A3939573C5410B408ECCE
要使ChannelFactory WCF实体框架全部协同工作,您必须进入Context构造函数并添加以下内容:
我希望这有助于其他人 .
当使用DbContext API代码优先(EF 4.3)时,我必须这样做:
对于EntityFramework 6.0,我还必须更改配置:
除了不为整个POCO添加代理外,您还有其他几个选项:
1)创建一个包装器 . 在API中,您可能不希望将整个POCO公开给您的用户...因此创建一个只暴露您想要的东西的包装器对象,这也解决了代理问题 .
1.5)非常像1,但不是创建一个包装器,只需返回
anonymous type
(使用LINQ
)2)如果你不需要在应用程序范围内进行操作,那么在需要序列化的
Controller
中进行更有意义...或者更加本地化为Method
,包括using
,这里是每个Controller
实现:3)另一件事是如果你只需要那个db调用,最简单的方法就是将
AsNoTracking()
链接到你的调用中:您可以改为使用DTO并返回 . 无需关闭Proxycreationenabled属性 .