簡體   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