繁体   English   中英

为什么为什么不断收到“不支持其类型为原始类型集合或复杂类型的属性。”?

[英]Why do I keep getting “ Properties whose types are collection of primitives or complex types are not supported.”?

我有一个定义如下的实体(由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数据服务公开此类,则会出现以下异常:

服务器在处理请求时遇到错误。 异常消息是'DomainObjects.EntityFrameworkModel.Gac类型的'TransactionList'属性不是有效的属性。 不支持其类型为原始类型或复杂类型集合的属性。 有关更多详细信息,请参见服务器日志。 异常堆栈跟踪为:

在System.Data.Services.Providers.ReflectionServiceProvider.BuildTypeProperties(的ResourceType parentResourceType,IDictionary的2 knownTypes, IDictionary 2个childTypes,队列1 unvisitedTypes, IEnumerable 1个entitySets)在System.Data.Services.Providers.ReflectionServiceProvider.PopulateMetadataForTypes(IDictionary的2 knownTypes, IDictionary System.Data.Services.Providers.ReflectionServiceProvider.PopulateMetadata(IDictionary 2 knownTypes, IDictionary 2 childTypes,IDictionary 2 entitySets) at System.Data.Services.Providers.BaseServiceProvider.PopulateMetadata() at System.Data.Services.DataService 2个childTypes,队列1 unvisitedTypes, IEnumerable 1个EntitySets 2 entitySets) at System.Data.Services.Providers.BaseServiceProvider.PopulateMetadata() at System.Data.Services.DataService 1.CreateProvider()在System.Data.Services.DataService 1.EnsureProviderAndConfigForRequest() at System.Data.Services.DataService 1.HandleRequest()在System.Data.Services.DataService`1。 System.ServiceModel.Dispatcher.S上SyncInvoke的ProcessRequestForMessage(Stream messageBody)ProcessRequestForMessage(Object,Object [],Object []) yncMethodInvoker.Invoke(在System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&rpc)在System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc&rpc)在System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc&rpc) System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc&rpc)位于System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage31path.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc&rpc)在System.ServiceModel.Run rpc)位于System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage2(MessageRpc&rpc)位于System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage11(MessageRpc&rpc)位于System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage1(MessageRpc&Dispatcher) .MessageRpc.Process(布尔值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
}

您是否在Context类中公开了IQueryable类型的属性? 如果没有,那就是问题所在。 为了将一个类识别为一个实体,它必须在一个实体集中公开(在Context类上具有一个属性),并且必须具有一个键(启发式或DataServiceKey属性)。

还要注意,似乎您正在基于EF的数据存储上定义基于反射的服务。 这将带来更复杂查询的问题。 WCF DS为反射提供程序和EF提供程序生成的表达式树有些不同(由于这些表达式支持的有效表达式的空间而有必要)。 为反射提供程序生成的树并不总是与EF兼容(反之亦然)。

如果您可以共享更多的Context类,也许可以在不强制使用反射提供程序的情况下实现此目的。 我了解您通过该服务公开了多个数据库,但是如何运行哪个数据库来运行传入的请求呢? 如果可以通过单独查看请求来确定请求,并且每个请求只能在单个DB上运行,那么我认为CreateDataSource内部的逻辑就足够了。

我认为WCF尝试序列化TransactionList属性。 您可以放置​​告诉WCF跳过属性的属性(类似于[IgnoreDataMember]),或将该属性转换为方法GetTransationList()。

我认为您不能将泛型公开给Web服务。 通常,我不会将ADO.net数据实体公开给Web服务。 您应该从Web服务代码中提取数据类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM