【问题标题】:Workaround for generics in Entity Framework实体框架中泛型的解决方法
【发布时间】:2014-11-26 16:55:59
【问题描述】:

我知道 EntityFramework 不支持泛型。

例如,这个类不会被接受或映射:

public class Foo<T> {
   //...
}

但是我想知道是否存在解决方法。

我有一个BaseUser 类:

public class BaseUser {
     [Key]
     public int Key { get; set; }

     [Required]
     public string Username { get; set; }

     [Required]
     public string Password { get; set; }
}

我所有的安全逻辑都围绕着这个BaseUser。它还使用了一些其他实体,例如:ApplicationClient

ApplicationClient 依赖于 BaseUser 实体:

public class ApplicationClient {
     //... Other properties

     [ForeignKey("User")]
     public int UserKey { get; set; }
     public virtual BaseUser User { get; set; }
}

到目前为止,这工作正常。

但是,我的 API 的使用者可能会从 BaseUser 扩展并添加更多属性:

public class MyUser : BaseUser {
     public string Email { get; set; }
}

这搞砸了一切,因为ApplicationClient 的外键应该是对MyUser 表的引用,而不是BaseUser

BaseUser 表不应该存在,应该用MyUser 表替换。

所以,合乎逻辑的解决方案是这样的:

public class ApplicationClient<U> where U : BaseUser {
    //... Some other properties

    [ForeignKey("User")]
    public int UserKey { get; set; }
    public virtual U User { get; set; }
}

现在,当 EF 构建模型时。该类型将被解析,它将看到需要对 MyUser 的引用,而不是 BaseUser

很遗憾,EF 不支持泛型,因此会引发异常。

还有其他方法可以完成我想做的事情(或更好的方法)吗?

【问题讨论】:

    标签: c# .net entity-framework generics


    【解决方案1】:

    我对实体不是很熟悉,因为我通常更喜欢 NHibernate,它支持继承映射到不同的表。

    考虑到 EF 的局限性,我能想到的最佳解决方案是:

    1- 拥有一个具有键/值对列表的用户

    class User {
        public int Id{get;set;}
        List<UserProperty> UserProperties {get;set;}
    }
    
    class UserProperty{
        public int Id{get;set;}
        public User User {get;set;}
        public string Key {get;set;}
        public string Value {get;set;}
    }
    

    这样,您的客户可以根据需要添加任意数量的属性。您必须检查重复的密钥,这很困难,因此您的 UserProperty 列表最好保密,用户公开访问它的方法。

    2- 忘记它。如果需要,您的客户可以将您的用户映射到其用户的一对一属性。

    class User {
        public int Id{get;set;}
    }
    
    //Client Code
    class ClientUser {
        public int Id{get;set;}
        public User ApiUser {get;set;}
    }
    

    【讨论】:

      【解决方案2】:

      Entity Framework 确实支持所有规范的继承策略:每个类层次结构的表、每个类的表和每个具体类的表,但是您也必须映射新的派生类。在此处查看示例:http://weblogs.asp.net/ricardoperes/entity-framework-code-first-inheritance

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-23
        • 2011-08-29
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多