我有一个实体定义如下(代码由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 server encountered an error processing the request. The exception message is The property TransactionList on type DomainObjects.EntityFrameworkModel.Gac is not a valid property. Properties whose types are collection of primitives or complex types are not supported. . See server logs for more details. The exception stack trace is:
at System.Data.Services.Providers.ReflectionServiceProvider.BuildTypeProperties(ResourceType parentResourceType, IDictionary
2 knownTypes, IDictionary
2 childTypes, Queue1 unvisitedTypes, IEnumerable
1 entitySets) at System.Data.Services.Providers.ReflectionServiceProvider.PopulateMetadataForTypes(IDictionary2 knownTypes, IDictionary
2 childTypes, Queue1 unvisitedTypes, IEnumerable
1 entitySets) at System.Data.Services.Providers.ReflectionServiceProvider.PopulateMetadata(IDictionary2 knownTypes, IDictionary
2 childTypes, IDictionary2 entitySets) at System.Data.Services.Providers.BaseServiceProvider.PopulateMetadata() at System.Data.Services.DataService
1.CreateProvider() at System.Data.Services.DataService1.EnsureProviderAndConfigForRequest() at System.Data.Services.DataService
1.HandleRequest() at System.Data.Services.DataService`1.ProcessRequestForMessage(Stream messageBody) at SyncInvokeProcessRequestForMessage(Object , Object[] , Object[] ) at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs) at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc& rpc) at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc& rpc) at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)
类Gac包含如下定义的属性TransactionList:
public IQueryable<TransactionList> TransactionList
{
get { return _myContext.TransactionList.AsNoTracking(); }
}
Why do I get this exception? I do not see any helpful information in the WCF server log. One useful information for you can be that this entity is representing a database view. I already expose a similar entity which contains the same types of properties int, DateTime, string) and it is working.
** UPDATE ** Data service definiton added (I left out the IDisposable methods):
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
}