MikaelEliasson / EntityFramework.Utilities

Provides extensions for EntityFramework that doesn't exist out of the box like delete and update by query and bulk inserts
443 stars 175 forks source link

IncludeEFU - Sequence contains no matching element #33

Open vindberg opened 9 years ago

vindberg commented 9 years ago

Hi, im getting the "Sequence contains no matching element" when there is no entries in the included collection. Have tried to add DefaultIfEmpty with no luck. How should the query look like? Im selecting into a new class.

[InvalidOperationException: Sequence contains no matching element] System.Linq.Enumerable.First(IEnumerable1 source, Func2 predicate) +482 EntityFramework.Utilities.EFQueryHelpers.GetFKProperty(ReadOnlyCollection1 cSpaceTables) +334 EntityFramework.Utilities.EFQueryHelpers.GetForeignKeyGetter(ReadOnlyCollection1 cSpaceTables) +59 EntityFramework.Utilities.EFQueryHelpers.IncludeEFU(IQueryable1 query, DbContext context, Expression1 collectionSelector) +368

Thanks in advance!

titobf commented 9 years ago

Same problem here:

System.InvalidOperationException: Sequence contains no matching element at System.Linq.Enumerable.First[TSource](IEnumerable1 source, Func2 predicate) at EntityFramework.Utilities.EFQueryHelpers.GetFKProperty[T,TChild](ReadOnlyCollection1 cSpaceTables) at EntityFramework.Utilities.EFQueryHelpers.GetForeignKeyGetter[T,TChild](ReadOnlyCollection1 cSpaceTables) at EntityFramework.Utilities.EFQueryHelpers.IncludeEFU[T,TChild](IQueryable1 query, DbContext context, Expression1 collectionSelector)

MikaelEliasson commented 9 years ago

Are you using projections? I didn't figure out how to get that to work yet.

titobf commented 9 years ago

Hi Mikael. And thanks so much for your time.

This is my query:

IQueryable query = _unitOfWork.Courses.Query() .IncludeEFU(_unitOfWork.Context, c => c.PatientInteractions.Where(pi => pi.PatientId == userId)) .IncludeEFU(_unitOfWork.Context, c => c.Ratings.Where(r => r.AppUserId == userId)) .Where(c => !c.IsDeleted)

MikaelEliasson commented 9 years ago

Could you share classes? I'm interested in seeing the the foreign keys and navigation properties

zaideygrek commented 9 years ago

Hi Mickael. I have the same problem. Have you found a solution ? Thanks

zaideygrek commented 9 years ago

Ok I found, there was a problem navigation. Thanks a lot for utilities !

MikaelEliasson commented 9 years ago

@zaideygrek Could you share what the problem was? I will try to improve this part of the library.

titobf commented 9 years ago

Mikael, sorry I miss the notification of your message (I have to unwatch so many repositories).

I have added the source code to my project and I found the line where the exception is thrown:

EFQueryHelpers.cs line 173:

var fk = cSpaceChildType.NavigationProperties.First(n => n.ToEndMember.GetEntityType().Name == typeof(T).Name).GetDependentProperties().First();

The problem is that I'm querying over the Course class and including a navigation property that is defined in a parent class so this comparison doesn't succeed: n.ToEndMember.GetEntityType().Name == typeof(T).Name

n.ToEndMember.GetEntityType().Name returns "Product" typeof(T).Name returns "Course"

public abstract class Product : TrackableEntity
{
    public ICollection<Rating> Ratings { get; set; }
}

public class Course : Product
{
}

public class Rating : DomainEntity
{
    public int ProductId { get; set; }
    public Product Product { get; set; }
}

I'll try to find a solution for this.

titobf commented 9 years ago

Can't find a way to get the real type out from the EntityType and I'm not sure it will be possible. Here is an unanswered question about that: http://stackoverflow.com/questions/16700457/how-do-i-get-the-corresponding-poco-object-type-from-an-entity-framework-metadat

I was thinking about using typeof(Base).IsAssignableFrom(typeof(Derived)): http://stackoverflow.com/questions/2742276/in-c-how-do-i-check-if-a-type-is-a-subtype-or-the-type-of-an-object

MikaelEliasson commented 9 years ago

Thank you for the repro. I'll take a look

titobf commented 9 years ago

Mikael, I found another issue that is possibly related to this one.

The line 72 in EFQueryHelpers:

var baseType = typeof(T).BaseType != typeof(object) ? typeof(T).BaseType : typeof(T);

is throwing:

Mapping and metadata information could not be found for EntityType 'XXXXX.Entities.BaseClasses.TrackableEntity'.

if I replace that line with:

                var baseType = typeof(T);

it works (ugly hack);

TrackableEntity is an entity that almost all my entities derive from. It has common properties about change tracking (CreatedOn, ModifiedOn, etc).

I find so useful the filtering provided by IncludeEFU. EF should include a functionality like that. I don't want to use projections to do the filtering (http://stackoverflow.com/a/3544878/1454888) because I lose the auto-mapping of the properties.