【问题标题】:How to convert Collection of One Class type to Another Class Type collection in Entity Framework如何在实体框架中将一个类类型的集合转换为另一个类类型集合
【发布时间】:2014-09-03 13:53:15
【问题描述】:

我正在开发 Web Api,我必须创建数据传输对象以在应用程序的 UI 上显示数据。

我正在使用 Code First 方法,这是我的域类

   public class Employee
    {

        [Key]
        public int BusinessEntityId { get; set; }


        [Required]
        [MaxLength(50)]

        public string JobTitle { get; set; }

        [Required]
        [DataType(DataType.DateTime)]
        public DateTime BirthDate { get; set; }


        [Required]
        [MaxLength(1)]
        public string MaritalStatus { get; set; }

        [Required]
        [MaxLength(1)]
        public string Gender { get; set; }

        [Required]
        [DataType(DataType.DateTime)]
        public DateTime HireDate { get; set; }

        [Required]
        public Boolean SalariedFlag { get; set; }

        public ICollection<EmployeePayHistory> PayHistories { get; set; }

    }

这是我的数据传输对象 (DTO) 类

 public class EmployeePayHistoryListDTO
    {

        public int Id { get; set; }

        public DateTime RateChangeDate { get; set; }

        public Decimal Rate { get; set; }

        public Int16 PayFrequency { get; set; }

        public String JobTitle { get; set; }

        public String Gendre { get; set; }

    }

现在,由于 PayHistories 是我的域类中的集合,我正在做的是创建一个新类 其中集合了我的 DTO 类类型EmployeePayHistoryListDTO

 public class EmployeeRelatedCollections
    {
        public ICollection<EmployeePayHistoryListDTO> PayHistories { get; set; }
    }

所以我通过以下 EF 语句从我的存储库中正确获取数据

 _context.Employees.Include("PayHistories")
                                     .Include("PayHistories")                                 
                                     .Single(e=>e.BusinessEntityId==id);

但是我在将我的 Employee 类(域类)的集合转换为我的 DTO 类型的集合的地方出现错误,这里是代码

PayHistories = (from ph in employee.PayHistories
                            select new EmployeePayHistoryListDTO
                            {
                                Id = ph.BusinessEntityId,
                                RateChangeDate = ph.RateChangeDate,
                                Rate = ph.Rate,
                                PayFrequency = ph.PayFrequency,
                                JobTitle = ph.Employee.JobTitle,
                                Gendre = ph.Employee.Gender
                            }).ToList();


          I am getting following exception below is summary 

 System.NullReferenceException ,  
Additional Information: Object reference Not set to an instance of an object.

 Troubleshooting tips
 1.  Check to determine if the object is null before calling the method,
 2.  Use new keyword to create an object instance.

【问题讨论】:

  • 我认为您错过了错误粘贴:P
  • 是的,非常感谢,我现在再次编辑它,请再看一遍。
  • 空引用发生在哪里?

标签: c# linq entity-framework dto


【解决方案1】:

您似乎未能初始化您的员工对象。当发生空引用异常时,您应该能够通过将鼠标悬停在员工对象上来检查它的值并查看它是否为空。当您尝试访问 null 对象(在本例中为 PayHistories)上的字段时,会发生 nullreference 异常。

看看这段代码是否避免了异常:

if(employee!=null){
    if(employee.PayHistories.Any()){

        PayHistories = (from ph in employee.PayHistories
                        select new EmployeePayHistoryListDTO
                        {
                            Id = ph.BusinessEntityId,
                            RateChangeDate = ph.RateChangeDate,
                            Rate = ph.Rate,
                            PayFrequency = ph.PayFrequency,
                            JobTitle = ph.Employee.JobTitle,
                            Gendre = ph.Employee.Gender
                        }).ToList();
    }
}

【讨论】:

    【解决方案2】:

    发件人:

    PayHistories = (from ph in employee.PayHistories
                            select new EmployeePayHistoryListDTO
                            {
                                Id = ph.BusinessEntityId,
                                RateChangeDate = ph.RateChangeDate,
                                Rate = ph.Rate,
                                PayFrequency = ph.PayFrequency,
                                JobTitle = ph.Employee.JobTitle,
                                Gendre = ph.Employee.Gender
                            }).ToList();
    

    你能做到吗:

    PayHistories = (from ph in employee.PayHistories
                            select new EmployeePayHistoryListDTO
                            {
                                Id = ph.BusinessEntityId,
                                RateChangeDate = ph.RateChangeDate,
                                Rate = ph.Rate,
                                PayFrequency = ph.PayFrequency
    
                            }).ToList();
    

    看看异常是否仍然发生?

    根据您的查询,看起来像:

    Employee -> PaymentHistory -> Employee.
    

    在你的声明中:

    _context.Employees.Include("PayHistories")
                                     .Include("PayHistories")                                 
                                     .Single(e=>e.BusinessEntityId==id);
    

    看起来您不会在 PayHistories 之上包含额外的员工对象(您是否故意将其包含两次?)。我相信你也可以使用 linq 语句来获得更强类型的包含,例如

    .Include(i => i.PayHistories)
    

    希望对您有所帮助!

    【讨论】:

    • 如果我按照您建议的方式进行操作 .Include(i => i.PayHistories) 我会得到以下信息“无法转换字符串类型的 lamda 表达式,因为它不是委托类型”
    • 显然Include是一种扩展方法,你需要“使用System.Data.Entity”才能使用它。 PITA 我知道,我总是忘记它的名称空间,而且你不能右键单击解决。 stackoverflow.com/questions/4544756/…
    • 在这里你是正确的 100% 非常感谢你。但问题仍然存在@Kritner。
    【解决方案3】:

    确保employee.PayHistories 不包含空条目,或在查询中检查:

    PayHistories = (from ph in employee.PayHistories where null != ph
    etc. . .
    

    此外,您指的是“ph”(员工)上可能延迟加载/未初始化的属性,该属性也可能为空。

    【讨论】:

    • 如果员工为空,这仍然会抛出异常。
    • 那是正确的 - 我会将奇怪的 SLQy linq 代码转换为扩展方法调用,以便在错误检查中获得更多的灵活性。
    【解决方案4】:

    这是我解决问题的方法。我有多个引用,但没有正确加载。

    有两种方法

    方法一。

    包含Expression&lt;Func&lt;T,U&gt;&gt; 的扩展方法重载

    _context.Employees.Include("PayHistories.furtherreferencename").Include("PayHistories.furtherReference");
    

    方法 2。

    使用强类型的 Include 方法。

    _context.Employees.Include(i=&gt;i.PayHistories.select(e=&gt;e.FurtherReference)).Include(i=&gt;i.PayHistories.select(e=&gt;e.FurtherReference));

    【讨论】:

      猜你喜欢
      • 2021-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-18
      • 1970-01-01
      • 2018-10-26
      • 1970-01-01
      • 2010-10-30
      相关资源
      最近更新 更多