【问题标题】:Linq to Objects to query LLBLGen projectionLinq to Objects 查询 LLBLGen 投影
【发布时间】:2013-03-21 08:24:50
【问题描述】:

我正在尝试使用推荐的 LLBLGen 语法来查询投影 (http://www.llblgen.com/documentation/3.5/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/gencode_usingentityview_adapter.htm#projections)

IEntityView2 view = table.DefaultView;
List<A1AllocationHelp1TableDTO> something = 
    (from c in view
     select new A1AllocationHelp1TableDTO
     {
         RecordStatus = c.RecordStatus,
         UniqueIdent = c.UniqueIdent
     }).ToList();

但我在“选择”时收到此错误:

The type arguments for method 'IEnumerable<TResult>
System.Linq.Enumerable.Select<TSource, TResult>(this IEnumerable<TSource>,
Func<TSource, TResult>)' cannot be inferred from the query.

有趣的是,在 VB.Net 中同样可以正常工作

Dim view As IEntityView2 = table.DefaultView
Dim something As List(Of A1AllocationHelp1TableDTO) = _
    (From c In view
     Select New A1AllocationHelp1TableDTO With _
          {
              .RecordStatus = c.RecordStatus, _
              .UniqueIdent = c.UniqueIdent
          }).ToList()

我正在使用 VS2010、.NET 4 和 LLBLGen 2.6。 不知道如何解决这个问题,谁能帮帮我?

谢谢

编辑:

IEntityView2 由 LLBLGen 生成,这是它的定义

public interface IEntityView2 : IEnumerable
{
    bool AllowEdit { get; set; }
    bool AllowNew { get; set; }
    bool AllowRemove { get; set; }
    int Count { get; }
    PostCollectionChangeAction DataChangeAction { get; set; }
    IPredicate Filter { get; set; }
    IEntityCollection2 RelatedCollection { get; }
    ISortExpression Sorter { get; set; }
    IEntity2 this[int index] { get; }
    event ListChangedEventHandler ListChanged;
    bool Contains(IEntity2 value);
    void CreateProjection(List<IEntityPropertyProjector> propertyProjectors, DataTable destination);
    void CreateProjection(List<IEntityPropertyProjector> propertyProjectors, IEntityCollection2 destination);
    void CreateProjection(List<IEntityPropertyProjector> propertyProjectors, IEntityDataProjector projector);
    void CreateProjection(List<IEntityPropertyProjector> propertyProjectors, DataTable destination, bool allowDuplicates);
    void CreateProjection(List<IEntityPropertyProjector> propertyProjectors, IEntityCollection2 destination, bool allowDuplicates);
    void CreateProjection(List<IEntityPropertyProjector> propertyProjectors, IEntityDataProjector projector, bool allowDuplicates);
    void CreateProjection(List<IEntityPropertyProjector> propertyProjectors, DataTable destination, bool allowDuplicates, IPredicate filter);
    void CreateProjection(List<IEntityPropertyProjector> propertyProjectors, IEntityCollection2 destination, bool allowDuplicates, IPredicate filter);
    void CreateProjection(List<IEntityPropertyProjector> propertyProjectors, IEntityDataProjector projector, bool allowDuplicates, IPredicate filter);
    int IndexOf(IEntity2 value);
    IEntityCollection2 ToEntityCollection();
    IEntityCollection2 ToEntityCollection(int startIndex);
}

【问题讨论】:

  • 请显示IEntityView2的定义。
  • 我已编辑添加定义

标签: c# linq-to-objects llblgenpro


【解决方案1】:

IEntityView2 继承了非泛型接口IEnumerable。但是,Select 方法需要通用版本。这就是您收到错误消息的原因。

假设您要访问的属性是在IEntity2 上定义的,以下将起作用:

view.Cast<IEntity2>()
    .Select(c => new A1AllocationHelp1TableDTO
           {
               RecordStatus = c.RecordStatus,
               UniqueIdent = c.UniqueIdent
           })
    .ToList();

它可以在 VB.NET 中工作,因为它使用后期绑定。您可以在以下示例中轻松看到这一点:

Dim view As IEntityView2 = table.DefaultView
Dim something As List(Of A1AllocationHelp1TableDTO) = _
(From c In view
 Select New A1AllocationHelp1TableDTO With _
      {
          .RecordStatus = c.IDontExist _
      }).ToList()

我正在使用一个不存在的属性 (IDontExist)。此代码仍会编译,但在运行时会抛出异常:

MissingMemberException: Public member 'IDontExist' on type 'IEntity2' not found.
   at Microsoft.VisualBasic.CompilerServices.Symbols.Container.GetMembers(String& MemberName, Boolean ReportErrors)
   at Microsoft.VisualBasic.CompilerServices.NewLateBinding.ObjectLateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)
   at Microsoft.VisualBasic.CompilerServices.NewLateBinding.LateGet(Object Instance, Type Type, String MemberName, Object[] Arguments, String[] ArgumentNames, Type[] TypeArguments, Boolean[] CopyBack)
   at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source) 

【讨论】:

  • 演员阵容实际上是为了查看.Cast().Select(c =>... 但这正是我所需要的
  • @kooshka:但是为什么要选择呢?如果view 中的项目已经属于目标对象,那么您需要做的就是:view.Cast&lt;A1AllocationHelp1TableDTO&gt;().ToList();。无需创建新对象。
  • 我的错。我的意思是 Cast。视图包含仅在运行时定义的 A1AllocationHelp1Entity 的实例,因为这是在 WCF 中,所以我需要返回一个静态定义的 DTO
【解决方案2】:

.DefaultView 返回一个类型化的视图,它实现了 IEntityView2,但你不应该将它强制转换为 IEntityView2,因为你会丢失泛型类型。所以你应该这样做:

List<A1AllocationHelp1TableDTO> something = 
    (from c in table.DefaultView
     select new A1AllocationHelp1TableDTO
     {
         RecordStatus = c.RecordStatus,
         UniqueIdent = c.UniqueIdent
     }).ToList();

这样,编译器就知道视图的泛型类型。

【讨论】:

  • 谢谢 Frans,但这也不起作用,我仍然遇到同样的错误。表的类型为 IEntityCollection2
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多