【问题标题】:Entity Framework Code First navigational properties returning null fields返回空字段的实体框架代码优先导航属性
【发布时间】:2013-03-23 19:06:45
【问题描述】:

对于我第一次使用 EF 代码的程序。过去我使用 linq to SQL en 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"));
    }
}

delivery 类是一个公共类,如下所示:

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

    ....lots of public properties

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

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();

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

【问题讨论】:

  • 在您的 Context 构造函数中添加以下行:Configuration.LazyLoadingEnabled = true; Configuration.ProxyCreationEnabled = true;
  • 试过了,但没有成功解决我的问题。

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


【解决方案1】:

必须从Record构造函数中去掉导航references的初始化,空导航collection的初始化就OK了:

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

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

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

【讨论】:

    【解决方案2】:

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

    如果您不想启用延迟加载,则应在查询中使用 Include 以包含交付信息。 Here你可以了解一些如何使用包含的信息。

    【讨论】:

    • 我想要延迟加载,但是使用codefirst时应该默认启用延迟加载。延迟加载似乎有效,因为我得到了一个交付的实例,只是没有从数据库中加载任何字段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多