【问题标题】:Entity Framework navigation property not working?实体框架导航属性不起作用?
【发布时间】:2016-05-04 14:11:53
【问题描述】:

我仍在学习 EF,并且正在尝试学习如何使用 ViewModel 和 JOIN 与多个表。研究我想我找到了如何做到这一点,但它不起作用。

我有两个表,CustomerCall 和 CallStatus。客户呼叫有一个 Status (int) 字段,CallStatus 将具有状态的显示名称。所以我需要把它们一起加入。

在我的研究中,我的 ViewModel 中似乎需要一个 Navagation 属性,然后使用 .Include 的 EF。因此,我在 CustomerCall.Status 和 CallStatus.Id 之间的 SQL 中创建了一个 FK。

这是我的班级和视图模型

[Table("CustomerCall")]
public partial class CustomerCall
{
    public int Id { get; set; }

    [StringLength(50)]
    public string CustomerName { get; set; }

    [StringLength(50)]
    public string Subject { get; set; }

    [Column(TypeName = "text")]
    public string Comment { get; set; }

    public DateTime? CallDate { get; set; }

    public int? Status { get; set; }

    public int? AssignedTo { get; set; }

    public DateTime? CreateDate { get; set; }
}

public partial class CallStatus
{
    public int Id { get; set; }

    [StringLength(25)]
    public string StatusName { get; set; }
}

public class CustomerCallVM
{
    public int Id { get; set; }

    [DisplayName("Customer Name")]
    public string CustomerName { get; set; }

    public string Subject { get; set; }

    public string Comment { get; set; }

    [DisplayName("Call Date")]
    public DateTime? CallDate { get; set; }

    public int? Status { get; set; }

    [DisplayName("Status")]
    public string StatusName { get; set; }

    public int? AssignedTo { get; set; }

    [DisplayName("Assigned To")]
    public string AssignedToName { get; set; }

    [DisplayName("Create Date")]
    public DateTime? CreateDate { get; set; }


    public CallStatus CallStatus { get; set; }

}

这是我正在尝试使用的存储库中的 EF,但我收到错误消息“指定的包含路径无效。EntityType 'CPPCustomerCall.ViewModels.CustomerCall' 未声明名为“CallStatus”的导航属性'"

public CustomerCallVM SelectById(int? id)
{
    using (DataContext db = new DataContext())
    {
        db.Configuration.AutoDetectChangesEnabled = false;      //no changes needed so turn off for performance.

        CustomerCallVM customerCall = new CustomerCallVM();

        var call = db.CustomerCalls.Include("CallStatus").Where(c => c.Id == id).FirstOrDefault();


        return customerCall;
    }
}

【问题讨论】:

    标签: c# asp.net-mvc entity-framework


    【解决方案1】:

    我的 ViewModel 中需要一个 Navagation 属性

    不,这行不通。实体框架对您的视图模型一无所知,也不知道 CustomerCall 和 CallStatus 之间的关系。您需要实体模型中的导航属性CustomerCall。

    您还需要CallStatusVM。

    然后你就可以查询你的数据库了:

    var customerCall = db.CustomerCalls.Include(c => c.CallStatus).Where(...).FirstOrDefault();
    

    然后您可以将其映射到您的视图模型:

    var customerCallVM = new CustomerCallVM
    {
        Id = customerCall.Id,
        CustomerName = customerCall.CustomerName,
        // ...
        CallStatus = new CallStatusVM
        {
            Id = customerCall.CallStatus.Id,
            StatusName = customerCall.CallStatus.StatusName,
        }
    };
    

    使用 AutoMapper 可以使后者变得更容易。

    【讨论】:

    • 我觉得this总结了我自己对automapper的感受。 “手工绘制的地图代码更快、更容易理解、更容易维护。”
    • 感谢您的帮助。不知道为什么我需要 CallStatusVM。我认为虚拟机的整个想法是用我想要的数据来塑造类。所以我的 CustomerCallVM 只有一个 StatusName,因为这是我要显示的唯一内容。
    • 我认为这会让我朝着正确的方向前进。
    • @Caverman 好吧,但从你的问题中并不清楚。如果你想要customerCallVM.StatusName = customerCall.CallStatus.StatusName,那么你确实不需要CallStatusVM。
    • 我将 CallStatus 属性从我的 VM 中取出,并将其放入我的 CustomerCall 实体中。然后尝试“var call = db.CustomerCalls.Include(s => s.CallStatus).Where(c => c.Id == id).FirstOrDefault;”但我收到一个错误,s.CallStatus 说“无法将 lambda 表达式转换为类型字符串,因为它不是委托类型。我需要对我放在 CustomerCall 实体类中的“CallStatus”属性做任何特别的事情来让它知道它是导航属性吗?
    【解决方案2】:

    您收到的错误是告诉您需要一个导航属性。 .Include() 是急切加载。这种加载需要将实体加载到某些东西中。那东西就是导航属性。

    下面的代码是您的 CustomerCall 类在添加了导航属性后所需要的样子。

    [Table("CustomerCall")]
    public partial class CustomerCall
    {
        public int Id { get; set; }
    
        [StringLength(50)]
        public string CustomerName { get; set; }
    
        [StringLength(50)]
        public string Subject { get; set; }
    
        [Column(TypeName = "text")]
        public string Comment { get; set; }
    
        public DateTime? CallDate { get; set; }
    
        public int? Status { get; set; }
    
        public int? AssignedTo { get; set; }
    
        public DateTime? CreateDate { get; set; }
    
        //This is your navigation property
        [ForeignKey("Status")]
        public virtual CallStatus CallStatus { get; set; }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-29
      • 2016-05-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多