繁体   English   中英

实体框架中泛型的变通办法

[英]Workaround for generics in Entity Framework

我知道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不支持泛型,因此会引发异常。

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

我对实体不是很熟悉,因为我通常更喜欢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;}
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM