使用LINQ和TPT EF时如何转换为子类?

Alv*_*aro 8 entity-framework casting ef-code-first

我有以下类层次结构:

public class RealPeople { }

public class Users : RealPeople { }
public class People : RealPeople { }
Run Code Online (Sandbox Code Playgroud)

在我的dbContext中,我为RealPeopleOnModelCreating过程定义了一个dbSet ,我为People和Users指定了单独的表:

modelBuilder.Entity<Users>().ToTable("Users");
modelBuilder.Entity<People>().ToTable("People");
Run Code Online (Sandbox Code Playgroud)

这将在我的数据库中创建相应的完整层次结构,并带有3个相应的表.当我想要检索Users我的数据库中的列表时出现问题.这个:

List = (from Reg in PersistentMgr.RealPeople select (Users)Reg)
       .ToList();
Run Code Online (Sandbox Code Playgroud)

或这个:

List = (from Reg in PersistentMgr.RealPeople select (Users)((RealPeople)Reg))
       .ToList();
Run Code Online (Sandbox Code Playgroud)

引发异常:

LINQ只能转换原始模型类型.

所以问题是,我无法将RealPeople转换为相应的子类Users.关于这个的任何想法?

Ger*_*old 10

获取子类集合的方法是使用OfType:

var users = (from p in PersistentMgr.RealPeople select p).OfType<User>();
Run Code Online (Sandbox Code Playgroud)

  • 轻微优化.在设置源之后立即放置OfType,以便查询的其余部分使用正确的类型实例.`var users = from p in PersistentMgr.RealPeople.OfType <User>()select p;` (3认同)

rik*_*kit 5

尝试以下方法:

var list = PersistentMgr.RealPeople.Select(reg => reg as Users).ToList();
Run Code Online (Sandbox Code Playgroud)

更好:

var list = PersistentMgr.RealPeople.Select(reg => (reg is Users) ? reg as Users : null).ToList();
Run Code Online (Sandbox Code Playgroud)

如果您尝试此操作,则会得到相同的错误:

var realperson = new RealPeople();
var user = (Users) realperson;
Run Code Online (Sandbox Code Playgroud)

原因是因为编译器不知道如何通过简单的转换将复杂类型转换为子类型-因此您需要使用as关键字。这将返回null,或者将超类型转换为子类型。

var realperson = new RealPeople();
var user = realperson as Users; // user is realperson converted into a Users object
var aString = "this is a string";
var otheruser = aString as Users; // otheruser is null, because aString was not a valid supertype for Users
Run Code Online (Sandbox Code Playgroud)

  • 令人惊讶的是,EF使用强制转换符和`as`转换符来转换强制转换。当我将代码从演员表切换为as时,我不敢相信它开始起作用。这并不是OP真正存在的问题,但是您的建议是关键。 (3认同)