سؤال

I'm trying to use the recommended LLBLGen syntax to query a projection (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();

But I'm getting this error on 'select':

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.

Funny is that the same works just fine in 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()

I'm using VS2010, .NET 4 and LLBLGen 2.6. Can't figure out how to fix this can anyone give me a hand?

Thanks

Edit:

IEntityView2 is generated by LLBLGen and this is its definition

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 inherits the non-generic interface IEnumerable. The Select method however needs the generic version. That's why you are getting the error.

Assuming that the properties you want to access are defined on IEntity2, the following will work:

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

It works in VB.NET because it uses late binding. You can easily see this on the following sample:

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

I am using a property that doesn't exist (IDontExist). This code will still compile but throw an exception at runtime:

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) 

نصائح أخرى

.DefaultView returns a typed view, which implements IEntityView2, but you shouldn't cast it to IEntityView2, as you then lose the generic type. So you should have done:

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

This way, the compiler knows the generic type of the view.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top