ekk*_*kis 3 c# entity-framework casting downcast asp.net-mvc-3
我有一个项目,我在EF中定义了Employer一个派生类User.在我的过程中,我创建了一个用户而不知道它最终是否会成为雇主(或其他类型的用户),之后我需要转换它.起初我尝试过(Intellisense表示存在显式转换):
Employer e = (Employer) GetUser();
Run Code Online (Sandbox Code Playgroud)
但在运行时我得到了:
Unable to cast object of type 'System.Data.Entity.DynamicProxies.User_7B...0D' to type 'Employer'.
Run Code Online (Sandbox Code Playgroud)
所以我试着写一个转换器:
public partial class User
{
public static explicit operator Employer(User u)
{
Run Code Online (Sandbox Code Playgroud)
但我得到错误:
Error 21 'User.explicit operator Employer(User)': user-defined
conversions to or from a derived class are not allowed
C:\Users\..\Documents\Visual Studio 2010\Projects\..\Website\Models\EF.Custom.cs
Run Code Online (Sandbox Code Playgroud)
精细.然后我重载了构造函数,Employer如下所示:
public partial class Employer
{
public Employer(User u)
{
this.Id = u.Id;
this.Claims = u.Claims;
// etc.
}
}
Run Code Online (Sandbox Code Playgroud)
并认为我可以这样做:
Employer e = new Employer(GetUser());
Run Code Online (Sandbox Code Playgroud)
但是当我运行它时,我得到错误:
System.InvalidOperationException was unhandled by user code
Message=Conflicting changes to the role 'User' of the
relationship 'EF.ClaimUser' have been detected.
Source=System.Data.Entity
StackTrace:
[...]
at Controllers.AuthController.Register(String Company, String GivenName,
String Surname, String Title, String Department) in C:\Users\..\Documents\
Visual Studio 2010\Projects\..\Website\Controllers\AuthController.cs:line
Run Code Online (Sandbox Code Playgroud)
作为最后的手段我尝试写这个:
Employer e = Auth.Claims("id")
.Where(x => x.Value == Auth.NameIdentifier())
.Select(x => x.User)
.Cast<Employer>()
.Single();
Run Code Online (Sandbox Code Playgroud)
... GetUser()返回一个User不提供类型的对象,.Cast<>所以我用直接查询到达那里......但我仍然得到了动态代理对象异常的转换.
所以我的问题是:当对象通过EF保持持久性时,我怎么能垂头丧气?
这不可能.您必须始终使用最终类型.将其创建为a后User,EF将永远不允许您将其更改为派生实体类型.
顺便说一句.对于面向对象的方法也是不可能的.您不能将父类的实例强制转换为派生类的实例(除非它确实是派生类的实例) - 它将在运行时抛出异常.重现问题的非常简单的示例:
class X { }
class Y : X { }
class Program
{
static void Main(string[] args)
{
X x1 = new Y();
Y y1 = (Y)x1; // Works
X x2 = new X();
Y y2 = (Y)x2; // InvalidCastException
}
}
Run Code Online (Sandbox Code Playgroud)
唯一的方法是覆盖转换运算符,它将在内部创建派生类的新实例,并将旧父实例中的所有字段复制到新派生的实例.
实体框架需要完全相同的方法.如果您从User实体开始,现在要将其提升为Employer实体,则必须删除旧用户并创建新用户Employer.
| 归档时间: |
|
| 查看次数: |
2847 次 |
| 最近记录: |