簡體   English   中英

EF Core,同一基類的每層表和引用實體產生錯誤

[英]EF Core, table-per-hierarchy and referencing entity of the same base class generates error

我們的聯系人是通過每個層次的表存儲的,聯系人是公司或個人,而一個人始終屬於公司。 兩者都從聯系繼承。

使用EF Core 2.1。

看起來像這樣

public abstract class Contact {
    public virtual Guid Id { get; set; }
    public virtual ICollection<Source> Sources{ set; get; } = new Collection<Source>();
}

public class Company : Contact {
    public string CompanyName { set; get; }
    public virtual ICollection<Person> People { set; get; } = new Collection<Person>();
}

public class Person: Contact {
    public string Name { set; get; }
    public DateTime Birthday { set; get; }
    public virtual Company Company { set; get; }
}

到目前為止,我們現在要做的是查詢“ Sources並包括contacts (所有contacts ,對於個人或公司而言都沒有關系)

context.Contact.Include(c => c.Contact).FirstOrDefault();

這將產生以下異常

Unable to cast object of type 'System.DateTime' to type 'System.Nullable``1[System.Guid]'.'

堆棧跟蹤

 at lambda_method(Closure , ValueBuffer )
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalMixedEntityEntry..ctor(IStateManager stateManager, IEntityType entityType, Object entity, ValueBuffer& valueBuffer)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntryFactory.NewInternalEntityEntry(IStateManager stateManager, IEntityType entityType, Object entity, ValueBuffer& valueBuffer)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.StartTrackingFromQuery(IEntityType baseEntityType, Object entity, ValueBuffer& valueBuffer, ISet`1 handledForeignKeys)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryBuffer.StartTracking(Object entity, IEntityType entityType)
   at lambda_method(Closure , QueryContext , AdSourceCrm , Object[] )
   at Microsoft.EntityFrameworkCore.Query.Internal.IncludeCompiler._Include[TEntity](QueryContext queryContext, TEntity entity, Object[] included, Action`3 fixup)
   at lambda_method(Closure , TransparentIdentifier`2 )
   at System.Linq.Enumerable.SelectEnumerableIterator`2.MoveNext()
   at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Boolean& found)
   at lambda_method(Closure )
   at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ResultEnumerable`1.GetEnumerator()
   at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider._TrackEntities[TOut,TIn](IEnumerable`1 results, QueryContext queryContext, IList`1 entityTrackingInfos, IList`1 entityAccessors)+MoveNext()
   at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext()
   at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Boolean& found)
   at System.Linq.Enumerable.First[TSource](IEnumerable`1 source)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass15_1`1.<CompileQueryCore>b__0(QueryContext qc)
   at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
   at EfTest.Program.Main(String[] args) in Program.cs:line 18

我們已經花了幾個小時(更像是幾天)試圖找到原因並進行修復,但無濟於事。

EF Core某種程度上與我們的構造發生了沖突(也許構造本身是錯誤的)

如果禁用LazyLoading,問題將消失。

任何想法是什么原因,什么可以解決此問題?

編輯2我刪除了Sources因為它們似乎不涉及問題

編輯3我添加了一個示例回購

只需將DbContextFactory中的ConnectionString更改為本地路徑即可。

我可以使用EF Core 2.1.4和2.2預覽版中提供的存儲庫來重現它。

正如您在上一次更新中提到的那樣,問題某種程度上與延遲加載(代理?)有關,因為沒有使用UseLazyLoadingProxies() ,代碼按預期工作了(這就是為什么我最初無法重現它的原因)。

由於這顯然是EF Core錯誤,因此您只能將其報告給EF Core問題跟蹤器並等待修復。 不幸的是,薄霧可能不會在即將發布的2.2版本中包含,但誰知道,值得嘗試。

在我看來,就像Entity Framework中的錯誤一樣,您可以通過顯式指定自動生成的屬性來防止這種情況發生,例如,將CompanyId屬性顯式添加到Person類

這樣可以防止EF Core將Birthday列錯誤映射到CompanyId列

public class Person : Base
{
    // ...

    public virtual Company Company { set; get; }    
    public Guid? CompanyId { get; set; }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM