实体框架代码返回空字段的第一个导航属性

时间:2013-03-23 19:06:45

标签: c# ef-code-first entity-framework-5

对于我第一次使用EF代码的程序。在过去,我使用linq to SQL和EF DbFirst。当检索主记录时,我无法使用导航属性加载子记录。我得到一个空的子记录,所有记录字段都是0或null。

当我想申请急切加载时。 .Include(x => x .......)没有显示我的导航。

我已经设置了以下类:

public Record()
    {
        Shipping = new ShippingData();
        Delivery = new DeliveryData();
        Items = new List<Item>();
        ImportDate = DateTime.Now;
    }

    [Key]
    public int RecordId { get; set; }
    public int ShippingId { get; set; }
    public int DeliveryId { get; set; }
    public DateTime ImportDate { get; set; }

    public virtual ShippingData Shipping { get; set; }
    public virtual DeliveryData Delivery { get; set; }
    public virtual List<Item> Items { get; set; }
    public virtual Collecting CollectingOrder { get; set; }

具有以下背景:

public class TweemansContext : DbContext
{
    public TweemansContext()
        : base("xxxx")
    {
    }

    public DbSet<Add.Record> Records { get; set; }
    public DbSet<Add.ShippingData> Shipping { get; set; }
    public DbSet<Add.DeliveryData> Delivery { get; set; }
    public DbSet<Add.Item> ProductItems { get; set; }
    public DbSet<Add.Kolli> Kolli { get; set; }
    public DbSet<Add.Collecting> CollectingOrders { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<Record>().HasRequired(s => s.Shipping)
                    .WithMany()
                    .HasForeignKey(s => s.ShippingId);
        modelBuilder.Entity<Record>().HasRequired(d => d.Delivery)
                    .WithMany()
                    .HasForeignKey(d => d.DeliveryId);
        modelBuilder.Entity<Record>().HasOptional(c => c.CollectingOrder)
                    .WithOptionalDependent(a => a.Record).Map(p => p.MapKey("CollectionID"));
    }
}

交付类是公共类,如下:

    public class DeliveryData
{
    [Key]
    public int DeliveryId { get; set; }
    public virtual Record Record { get; set; }

    ....lots of public properties

现在,当我尝试使用延迟加载时,使用以下代码将交付类的所有属性都为null:

using (TweemansContext context = new TweemansContext())
        {
            var imported = (from record in context.Records
                            where record.ImportDate.Year == date.Year && record.ImportDate.Month == date.Month && record.ImportDate.Day == date.Day
                            select record).ToList();

            foreach (var Record in imported)
            {
                string email;
                string telnr;
                CustomerService service = new CustomerService(connectionString);
                **string servicenr = Record.Delivery.AccountNumber.Substring(2, 8);**
                service.GetUserData(servicenr, out email, out telnr);
                Record.Delivery.Email = email;
                Record.Delivery.TelephoneNbr = telnr;
            }
            context.SaveChanges();
        }
使用**我的调试器的行上的

告诉我交付存在,但所有属性都为空。

如果想要按如下方式应用包含,则.include不会显示我的导航:

    var imported = (from record in context.Records.Include(x=>x.)
                            where 
                               record.ImportDate.Year == date.Year 
                               && record.ImportDate.Month == date.Month
                               && record.ImportDate.Day == date.Day
                            select record).ToList();

我做错了什么,或者我误解了哪一部分?

2 个答案:

答案 0 :(得分:4)

您必须从Record构造函数中删除导航引用的初始化,空导航集合的初始化正常:

Shipping = new ShippingData(); // remove this line
Delivery = new DeliveryData(); // remove this line

基本上这些行使用ShippingDataDeliveryData的构造函数设置的值“覆盖”加载的数据,可能是默认值0null

关于你的评论的附注“ .Include(x =&gt; x .......)没有显示我的导航”。您需要将using System.Data.Entity;放在代码文件的开头,以使Include扩展方法可用,将lambda表达式作为参数。

答案 1 :(得分:0)

当你的调试停在那里时,你应该在Delivery上获得一个代理类。如果你没有得到这个,你应该在你的上下文中启用延迟加载。您可以查看here如何启用延迟加载。

如果您不想启用延迟加载,则应在查询中使用“包含”以包含“传递”信息。 Here您可以获得一些有关如何使用include的信息。