【问题标题】:EntityFreamwork full entity and lite entityEntityFreamwork 完整实体和精简实体
【发布时间】:2019-03-10 01:43:12
【问题描述】:

我有表用户

用户表:

Id, Name , firstName , password , email , address , dateofBrith

我想为用户表创建两个实体,一个是精简版,另一个是完整的

[Table("user")]
public class LiteUser 
{
   public int ID {get;set;}
   public string Name {get;set;}
   public int firstName{get;set;}
} 

第二个实体

public class fullUser : LiteUser
{   
       public date dateofBrith {get;set;}
       public string password {get;set;}
       public string email {get;set;}
       public string address {get;set;}

}

但我没有得到关于没有列鉴别器的错误

可以像我的实体一样做一些事情,但一个比另一个实体有更多的文件

提前感谢您的帮助

【问题讨论】:

  • 将您的完整用户映射到您的表。如果您在编码过程中不需要所有字段,请使用projection 仅返回您需要的字段。
  • @Fran 非常适合投影。如果您不喜欢使用 LINQ,则始终可以将 EF 实体(完整)映射到称为 LiteUser 的 DTO。根据设计,每个表一个 EF 实体。
  • @JohnWhite >每个表一个 EF 实体entities across tables 表,您可以在每个层次结构的[单表] (weblogs.asp.net/manavi/…) 表中拥有具有继承性的实体。但这是更多涉及的场景。
  • @Fran 在 EF6 和后面,是的。我实际上在几个场景中运行。在 EF Core 中,没有,我不知道添加它的计划。对于这个 OP,这是解决他的场景的最简单的回应。不同的情况需要更复杂、更细致的反应。但感谢您提供额外的链接。

标签: c# entity-framework


【解决方案1】:

一种选择是使用表拆分,即将单个表映射到两个或多个实体。与您请求的解决方案的不同之处在于“完整”配置中的“附加”属性将由另一种实体类型表示。示例(对于 EF Core;EF6 将非常相似):

public class SplitTablePrincipal
{
    [Key]
    public int Id { get; set; }
    public string PrincipalProperty { get; set; }
    // principal entity has a nav property to the dependent entity
    public virtual SplitTableDependent Dependent { get; set; }
}

public class SplitTableDependent
{
    [Key]
    public int Id { get; set; }
    public string DependentProperty { get; set; }
}

public class SplitTablePricipalConfiguration : IEntityTypeConfiguration<SplitTablePrincipal>
{
    public void Configure( EntityTypeBuilder<SplitTablePrincipal> builder )
    {
        //builder.HasKey( pe => pe.Id );
        // establish 1:? relationship w/ shared primary key
        builder.HasOne( pe => pe.Dependent )
            .WithOne()
            .HasForeignKey<SplitTableDependent>( de => de.Id ); // FK is PK
        builder.ToTable( "YourTableName" );
    }
}

public class SplitTableDependentConfiguration : IEntityTypeConfiguration<SplitTableDependent>
{
    public void Configure( EntityTypeBuilder<SplitTableDependent> builder )
    {
        //builder.HasKey( de => de.Id );
        // map dependent entity to same table as principal
        builder.ToTable( "YourTableName" ); // same table name
    }
}

您只需在DbContext 中包含SplitTablePrincipal 实体类型的DbSet。查询时,Dependent 属性默认不会被填充(你的“lite”配置);您需要通过.Include( stp =&gt; stp.Dependent ) 急切地加载“完整”数据配置的属性。如果您愿意,您还可以延迟加载或显式加载Dependent 属性。例如:

dbContext.Entry( principalEntity ).Reference( p => p.Dependent ).Load();

【讨论】:

    【解决方案2】:

    很遗憾,没有。一张表只能定义一个实体。相反,您必须手动执行。从完整实体中选择以返回自定义“Lite”条目,因为 EF 需要从一开始就知道与特定表相关的所有列。

    编辑:解决此问题的唯一方法是创建一个视图并映射到该视图。

    【讨论】:

    • 这是不正确的;表拆分允许将多个实体映射到单个表,但不是以问题中要求的方式
    • 呵呵,学到了新东西。因此,您可以让两个实体指向同一个表,但前提是它们不共享任何列。我不明白您为什么真的想要这样做,因为您可以轻松地选择您真正想要的数据并且查询会正确响应。相反,您必须在“子”表上执行包含操作,该表本身可能会很快变得混乱。归根结底,我开始倾向于使用 EF 进行保存,然后使用 Dapper 进行所有获取,因为它要快得多 - 但我也喜欢编写 SQL。 :)
    【解决方案3】:

    正如 Daniel 指出的那样,表可以与单个实体定义相关联,在 Table Per Hierarchy 继承之外,这不是您要寻找的。​​p>

    这是我在 NHibernate 中使用的一个旧技巧,EF 不支持它。

    借助 EF,您可以利用 Linq 和 ViewModel 来避免使用 Lite 和 Full 模型。

    给定:

    //Entity
    public class User
    {
       public int ID {get;set;}
       public string Name {get;set;}
       public int firstName{get;set;}
       public date dateofBrith {get;set;}
       public string password {get;set;}
       public string email {get;set;}
       public string address {get;set;}
    }
    
    // View Models...
    public class LiteUserViewModel 
    {
       public int ID {get;set;}
       public string Name {get;set;}
       public int firstName{get;set;}
    } 
    
    public class FullUserViewModel : LiteUserViewModel
    {   
       public date dateofBrith {get;set;}
       public string password {get;set;}
       public string email {get;set;}
       public string address {get;set;}
    } 
    

    查询中..

    //Give me a list of lite data..
    var viewModels = context.Users
        .Where(x => x.DateOfBirth < startDate)
        .Select(x => new LiteUserViewModel
        {
           UserId = x.UserId,
           Name = x.Name,
           FirstName = x.FirstName
        }).ToList();
    
    // Give me a full user.
    var viewModel = context.Users
        .Where(x => x.UserId = userId)
        .Select(x => new FullUserViewModel
        {
           UserId = x.UserId,
           // ... etc ...
        }).SingleOrDefault();
    

    您可以利用 AutoMapper 等库来处理将实体映射到视图模型。如果您只想检查不需要定义视图模型/ DTO 的数据,只需使用匿名类型。最终结果是相同的,因为 EF 将执行优化查询以仅返回您想要的数据而不是整个实体。您可以使用此技术优化视图模型以扁平化分层数据。您确实需要确保 .Select() 中的任何方法或转换都是纯的并且与 EF 兼容,因为 EF 将尝试将它们转换并传递给 SQL。更复杂的转换应该在视图模型本身中完成,或者使用原始数据的匿名类型选择,然后是 ToList/Single/等。然后 .Select() 通过 Linq2Object 通过适当的转换进入视图模型。

    【讨论】:

      【解决方案4】:

      你可以这样做

      [Table("user")]
      public class LiteUser 
      {
         public string Name {get;set;}
         public int firstName{get;set;}
      }
      
      public class fullUser : LiteUser
      {   
         public int ID {get;set;}
         public date dateofBrith {get;set;}
         public string password {get;set;}
         public string email {get;set;}
         public string address {get;set;}
      
      }
      

      在派生类中使用主键public int ID {get;set;}

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-10-13
        • 1970-01-01
        • 2017-02-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-22
        • 2011-09-02
        相关资源
        最近更新 更多