我有以下课程
public pratial class Address
{
public Guid AddressID{ get; set; }
public AddressType AddressType{ get; set; }
}
public partial class AddressType
{
public string TypeName{ get; set; }
}
在我的派生DBContext类中,我重写了OnModelCreating
protected override OnModelCreating(DBModelBuilder modelBuilder)
{
modelBuilder.Entity<Address>().HasKey( p => p.AddressID );
modelBuilder.Entity<Address>().Property ( p => p.AddressID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Address>().HasRequired( p => p.AddressType);
modelBuilder.Entity<AddrssType>().HasKey( p => p.TypeName );
...
}
这样可以很好地填写数据库中的记录
数据库中的我的表最终看起来像这样
Addresses Table
AddressID (PK, uniqueidentified, not null)
AddressType_TypeName(FK, nvarchar(32), not null)
AddressTypes Table
TypeName (PK, uniqueidentifies, not null)
现在我在表格中放了一些数据
AddressTypes记录 TypeName我放入了商业
地址记录中的AddressType_TypeName我放入了商业
当我对此进行单元测试时,我希望重新参加我的记录
List<Address> addresses = context.Addresses.ToList()
Assert.AreEqual(addresses[0].AddressType.TypeName, "Business");
但是这告诉我AddressType为null
如何设置Address和AddressType之间的关系,以便找回我已经连接的AddressType?
答案 0 :(得分:0)
要加载相关实体,您必须使用 eager loading 告诉它实体框架:
using System.Data.Entity;
//...
var addresses = context.Addresses.Include(a => a.AddressType).ToList()
...或延迟加载,如果您将导航属性标记为virtual
,则默认启用
public virtual AddressType AddressType { get; set; }
Eager loading在单个数据库往返中将父数据和相关数据加载在一起。延迟加载需要两次往返,当您访问行addresses[0].AddressType.TypeName
中的导航属性时,第二次发生在转换下。
修改强>
测试项目以显示此示例中的延迟加载(EF 5.0,.NET 4.0,SQL Server Express 2008 R2作为数据库)。我只将virtual
放在AddressType
前面。其余部分与您的模型完全相同:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
namespace EFLazyLoading
{
public partial class Address
{
public Guid AddressID{ get; set; }
public virtual AddressType AddressType{ get; set; }
}
public partial class AddressType
{
public string TypeName{ get; set; }
}
public class MyContext : DbContext
{
public DbSet<Address> Addresses { get; set; }
public DbSet<AddressType> AddressTypes { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Address>().HasKey( p => p.AddressID );
modelBuilder.Entity<Address>().Property ( p => p.AddressID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<Address>().HasRequired( p => p.AddressType);
modelBuilder.Entity<AddressType>().HasKey( p => p.TypeName );
}
}
class Program
{
static void Main(string[] args)
{
Database.SetInitializer(new DropCreateDatabaseAlways<MyContext>());
using (var ctx = new MyContext())
{
var address = new Address
{
AddressType = new AddressType { TypeName = "Business" }
};
ctx.Addresses.Add(address);
ctx.SaveChanges();
}
using (var ctx = new MyContext())
{
List<Address> addresses = ctx.Addresses.ToList();
string typeName = addresses[0].AddressType.TypeName;
}
}
}
}
最后一行中typeName
的结果符合预期: