【问题标题】:Inheritance from Entity Framework object从实体框架对象继承
【发布时间】:2012-11-19 16:30:45
【问题描述】:

我正在尝试设置从数据库中检索。 我有一个 EF(实体框架)对象 emUser 和一个从 emUser 继承的普通类 User,但添加了一些额外的功能。

public class User : emUser
{
    #region Properties
    public string Username
    {
        get { return Email; }
    }
    public string FullName
    {
        get { return FirstName + " " + LastName; }
    }
    #endregion
}

public partial class emUser : EntityObject
{
    [code ...]
}

由于某种原因,虽然 User 继承自 emUser 我无法显式转换它们。 我正在使用的代码:

List<User> returnUsers = new List<User>();
var users =
    (from u in edm.UserSet.OfType<emUser>()
    select u);

    if (users != null)
    {
        foreach (emUser user in users)
        {
            User newUser = (User)user;
            returnUsers.Add(newUser);
        }
    }
return returnUsers;

我可以让User 成为 emUser 的包装器,但是每次对 emUser 进行更改时我都必须更改它。我想用User来区分技术服务层和领域层使用的类。

我收到如下错误消息:

{System.InvalidCastException: Unable to cast object of type 'Services.emUser' to type 'Users.User'. at Services.DatabaseController.GetUsers() in [file path]:line 412}

为什么我不能将 emUser 转换为 User?

【问题讨论】:

  • UseremUser,但 emUser 不是 User。你不能那样做。
  • 您为什么希望这种低调有效? EF 只能返回 EMUser 对象——它知道的那些。对于它的价值,我认为模型层和服务层的并行数据结构是一个坏主意,也是对继承的不好使用。服务层与其下面的层进行通信的设计还不错。如果您需要使用不属于该层的模型类添加功能,请正交执行。 (使用以模型对象为参数的“常规”函数,或在服务层定义的扩展方法。)

标签: c# inheritance explicit-conversion


【解决方案1】:

您的问题是@millimoose 所说的:EF 只能返回emUser 对象,因为它不知道User 并且emUser 可能不是User

您可以从这里获得三种可能的解决方案:

  1. 设置User继承自EntityObject,然后让emUser继承自User。实施起来会很痛苦,而且不会给您带来任何有用的优势。
  2. 创建要传递的数据传输对象,您基本上将所有属性从emUser 复制到User 中(通常通过User 的构造函数)。这会给你想要的分离,但会很痛苦。
  3. 将额外的属性添加到emUser 的新partial 类中。这是我强烈推荐的,因为它简单明了。

这是一个例子:

// In a manually generated file in the same project
public partial class emUser
{
    #region Properties
    public string Username
    {
        get { return Email; }
    }
    public string FullName
    {
        get { return FirstName + " " + LastName; }
    }
    #endregion
}

// In the automatically generated file
public partial class emUser : EntityObject
{
    [code ...]
}

用法:

emUser foo = GetUser();
Console.WriteLine("FirstName: " + emUser.FirstName);
Console.WriteLine("FullName: " + emUser.FullName);

【讨论】:

  • 谢谢!这很有帮助。经过一番思考,我想出了相同的解决方案(第 3 个)。例如,如果我有一个通用接口,我可以用它来映射相同的属性等等,但在这种情况下,使用部分类可能是最好的解决方案!
  • @kumaheiyama - 绝对。这正是为什么几乎所有自动生成的代码(无论是来自 EF、L2S,甚至只是一个 winform)都作为部分类生成的原因 - 易于扩展。很高兴为您提供帮助!
【解决方案2】:

除非添加转换运算符,否则无法将基类转换为派生类。

public class User : emUser
{
    #region Properties
    public string Username
    {
        get { return Email; }
    }
    public string FullName
    {
        get { return FirstName + " " + LastName; }
    }
    #endregion

    public static explicit operator User (emUser user) 
    {
        User result = new User();
        // set properties
        return result;
    }
}

【讨论】:

  • 谢谢@Moe!这也是一个有用的解决方案,将来可能会使用它。
猜你喜欢
  • 1970-01-01
  • 2011-05-19
  • 2010-10-07
  • 1970-01-01
  • 2017-09-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多