【发布时间】:2011-11-21 14:52:42
【问题描述】:
我有一个实体定义如下(VS2010 POCO 生成器生成的代码):
public partial class TransactionList
{
public int tlRecordId { get; set; }
public Nullable<int> tlTracer { get; set; }
public Nullable<int> tlRecordType { get; set; }
public Nullable<int> tlPayType { get; set; }
public Nullable<int> pdmNumber { get; set; }
public string pdmName { get; set; }
public string zoneName { get; set; }
public string groupName { get; set; }
public Nullable<int> serviceCarNumber { get; set; }
public Nullable<int> moneyCarNumber { get; set; }
public Nullable<System.DateTime> tlPayDateTime { get; set; }
public Nullable<System.DateTime> tlExpDateTime { get; set; }
public Nullable<int> senderPdmNumber { get; set; }
public Nullable<int> tlAmount { get; set; }
public Nullable<int> tlTicketNo { get; set; }
}
并且这个类有第二个分部类(手动编写),它包含 Key 属性。
[DataServiceKey("tlRecordId")]
public partial class TransactionList
{ }
所以在这个类中没有定义复杂的类型/原始集合。如果我使用 WCF 数据服务公开此类,则会收到以下异常:
服务器在处理请求时遇到错误。例外 消息是 'The property 'TransactionList' on type “DomainObjects.EntityFrameworkModel.Gac”不是有效属性。 类型是基元或复杂类型的集合的属性 不支持。有关更多详细信息,请参阅服务器日志。例外 堆栈跟踪是:
在 System.Data.Services.Providers.ReflectionServiceProvider.BuildTypeProperties(资源类型 parentResourceType, IDictionary
2 knownTypes, IDictionary2 childTypes, Queue1 unvisitedTypes, IEnumerable1 entitySets) 在 System.Data.Services.Providers.ReflectionServiceProvider.PopulateMetadataForTypes(IDictionary2 knownTypes, IDictionary2 childTypes,Queue1 unvisitedTypes, IEnumerable1 entitySets)在 System.Data.Services.Providers.ReflectionServiceProvider.PopulateMetadata(IDictionary2 knownTypes, IDictionary2 childTypes, IDictionary2 entitySets) at System.Data.Services.Providers.BaseServiceProvider.PopulateMetadata() at System.Data.Services.DataService1.CreateProvider() 在 System.Data.Services.DataService1.EnsureProviderAndConfigForRequest() at System.Data.Services.DataService1.HandleRequest() 在 System.Data.Services.DataService`1.ProcessRequestForMessage(流 messageBody) 在 SyncInvokeProcessRequestForMessage(Object , Object[] , 对象[] ) 在 System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(对象 实例,Object[] 输入,Object[]& 输出)在 System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& RPC)在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& RPC)在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& RPC)在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& RPC)在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& RPC)在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& RPC)在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& RPC)在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& RPC)在 System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc) 在 System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
Gac 类包含定义如下的属性 TransactionList:
public IQueryable<TransactionList> TransactionList
{
get { return _myContext.TransactionList.AsNoTracking(); }
}
为什么会出现此异常?我在 WCF 服务器日志中看不到任何有用的信息。一个对您有用的信息可能是该实体表示数据库视图。我已经公开了一个类似的实体,它包含相同类型的属性 int、DateTime、string) 并且它正在工作。
** 更新 ** 添加了数据服务定义(我省略了 IDisposable 方法):
public class DummyService : DataService<CustomContext>
{
protected override CustomContext CreateDataSource()
{
//I need a single endpoint exposing data from more databases. Here I pass
//the data needed for the creation of connection strings
var dataSource = new CustomContext(new int []{1,2,3});
return dataSource;
}
}
///This class represents my single endpoint exposing data from various databases.
///Every database has the same DB schema.
public class CustomContext: IDisposable
{
private static IList<Gac> _gacList;
//Here I construct the list of accessible data sources - databases. This list
// can vary
public CustomContext(IEnumerable<AreaCodes> areaCodes)
{
//This is the list of various databases exposed via OData
_gacList = new List<Gac>();
foreach (AreaCodes ac in areaCodes)
{
//When calling the constructor of Gac, the DbContext gets created.
_gacList.Add(new Gac(ac.Id));
}
}
//the entity which will be exposed
public IQueryable<Gac> Gac
{
get { return _gacList != null ? _gacList.AsQueryable() : null; }
}
}
///This class represents a single data source - a database.
//All databases are exposed over single endpoint
[DataServiceKey("GacId")]
public class Gac: IDisposable
{
private MyContext _myContext;
private int _gacId;
public Gac(int areaCode)
{
//Here I finally create my context
_myContext= new MyContext("...Connection String Generated based on areaCode");
_myContext.Configuration.ProxyCreationEnabled = false;
_myContext.Configuration.LazyLoadingEnabled = false;
_gacId = areaCode;
}
//This property uniquely identifies a GAC object. It is an entity key.
public int GacId
{
get { return _gacId; }
}
//Expose an entity from the EF layer
public IQueryable<TransactionList> TransactionList
{
get { return _myContext.TransactionList.AsNoTracking(); }
}
//...Other about 25 IQueryable properties
}
//generated Entity Framework Conceptual Layer
public partial class MyContext: DbContext
{
//This entity represents my database view which I want to access to
public DbSet<TransactionList> TransactionList { get; set; }
//...Other about 25 generic DbSet properties
}
【问题讨论】:
-
您的数据服务是如何定义的?
-
'Gac' 是我的数据源中的一个类。此类包含一些属性(我要公开的每个实体一个) - 与上面的 TransactionList 相同。目前我可以毫无问题地公开大约 30 个实体,但如果我添加这个(TransactionList),则会显示异常。
-
之后,我可以像这样访问我的数据服务:localhost:6000/Gac(1)/TransactionList。
标签: c# entity-framework wcf-data-services odata