Вопрос

I've been using LinQ to SQL with EF for a while now and have just stumbled on some strange behaviour that hopefully someone may be able to explain for me.

I'm performing a LinQ query on a database context that has a POCO entity with virtual properties for related entities. I'm using a where clause to eliminate instances where that entity is null. I'm using Lazy Loading.

return this.runtimeContext.FatalExceptionLogs.Where(l => l.RuntimeToDesignJuicerRelationship != null);

What I'm finding is that when my query is evaluated LinQ to SQL seems to entirely ignore my condition that the virtual property is null as if I'd never included this check at all. Instead it returns all records in my dbset named FatalExceptionLogs.

Now I have a simple workaround for this which is to first load the data into memory using .ToList() then

This looks like so:

return this.runtimeContext.FatalExceptionLogs.ToList().Where(l => l.RuntimeToDesignJuicerRelationship != null);

Now the check is performed in memory and all instances where the virtual property is null are returned (because there is no corresponding record as the id which is used for the join is nullable) and we're all good.

I have also considered:

  • Checking if the id that is joined on is null but unfortunately I can't garauntee that the referential integrity of the table has been maintained as there is no foreign key applied urgh!.

  • Checking if there are any records in the other table with the matching id, but that could be rather inefficient.

So I have a way of working around this but I'd really like to understand why LinQ to Sql is doing this and what other options there are, can anyone help?

The full code if it helps is below though I've cut it down for this example:

The query:

return this.runtimeContext.FatalExceptionLogs.ToList().Where(l => l.RuntimeToDesignJuicerRelationship != null);

The entity:

public class FatalExceptionLog
{
    public int Id { get; set; }
    public int? RuntimeJuicerId { get; set; }
    public virtual RuntimeToDesignJuicerRelationship RuntimeToDesignJuicerRelationship { get; set; }
}

The mapping:

public class FatalExceptionLogMap : EntityTypeConfiguration<FatalExceptionLog>
{
    public FatalExceptionLogMap()
    {
        // Primary Key
        this.HasKey(t => t.Id);

        // Table & Column Mappings
        this.ToTable("FatalExceptionLogging");
        this.Property(t => t.RuntimeJuicerId).HasColumnName("JuicerLiveID");

        this.HasRequired(t => t.RuntimeToDesignJuicerRelationship)
            .WithMany(t => t.FatalExceptionLogs)
            .HasForeignKey(t => t.RuntimeJuicerId);
    }
}
Это было полезно?

Решение

Why NOT just do the normal joining?

return this.runtimeContext.FatalExceptionLogs.Where(
                    l => runtimeContext.RuntimeJuicers.Any(
                                    y => y.RuntimeJuicerId == l.RuntimeJuicerId
                                                            )
                                                    );
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top