Entity Framework 代码首先不初始化外键 class 成员

Entity Framework with code first not initializing Foreign Key class member

我正在使用 EF 6,代码优先,我有一个域模型 class,它有 2 个 FK 和相关对象作为 class 成员。插入工作正常,但是当从数据库中获取值时,与此对象相关的 FKs 对象为空。

我尝试将 Lazy Initialization 设置为 false 并将 FK class 成员标记为虚拟。我已经尝试过 Eagerly Loading,但仍然没有积极的结果(反正我不想使用 Eagerly)。

public class AffectedLocation
{
    public AffectedLocation()
    {
        Id = Guid.NewGuid();
    }

    [Key]
    [Required]
    public Guid Id { get; set; }

    [Required]
    public string Name { get; set; }
    public string Description { get; set; }

    [Required]
    [ForeignKey("RadiationLevel")]
    public Guid FK_RadiationLevel { get; set; }
    public virtual RadiationLevel RadiationLevel { get; set; }

    [Required]
    [ForeignKey("GeographicalCoordinates")]
    public Guid FK_GeographicalCoordinates { get; set; }
    public virtual GeographicalCoordinates GeographicalCoordinates { get; set; 
}

public class RadiationLevel
{
    public RadiationLevel()
    {
        Id = Guid.NewGuid();
    }

    [Key]
    public Guid Id { get; set; }

    [Required]
    public int Level { get; set; }

    public string Description { get; set; }
}

public class GeographicalCoordinates
{
    public GeographicalCoordinates()
    {
        Id = Guid.NewGuid();
    }

    [Key]
    public Guid Id { get; set; }

    [Required]
    public float Latitude { get; set; }

    [Required]
    public float Longitude { get; set; }

    [Required]
    public float Range { get; set; }
}

public class Repository<TEntity> : IRepository<TEntity> where TEntity : class
{
    protected readonly DbContext Context;

    public Repository(DbContext context)
    {
        Context = context;
    }

    public IEnumerable<TEntity> GetAll()
    {
        return Context.Set<TEntity>().ToList();
    }
}

public class LocationRepository : Repository<AffectedLocation>, ILocationRepository
{
    public LocationRepository(RadioactiveAreaContext context)
        : base(context)
    {

    }
}

public class UnitOfWork : IUnitOfWork
{
    private readonly RadioactiveAreaContext _context;

    public UnitOfWork()
    {
        _context = new RadioactiveAreaContext();
        Location = new LocationRepository(_context);
    }

    public ILocationRepository Location { get; private set; }

    public int Complete()
    {
        return _context.SaveChanges();
    }

    public void Dispose()
    {
        _context.Dispose();
    }
}

public class RadioactiveAreaContext : DbContext
{
    public RadioactiveAreaContext()
        : base("name=RadioactiveAreaContext")
    {
        this.Configuration.LazyLoadingEnabled = false;
    }

    public virtual DbSet<AffectedLocation> Locations { get; set; }
    public virtual DbSet<RadiationLevel> RadiationLevels { get; set; }
    public virtual DbSet<GeographicalCoordinates> GeographicalCoordinates { get; set; }
    
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new LocationConfiguration());
        modelBuilder.Configurations.Add(new RadiationLevelsConfiguration());
        modelBuilder.Configurations.Add(new GeographicalCoordinatesConfiguration());
    }
}


var unitOfWork = new UnitOfWork();

unitOfWork.Location.Add(someLocation);

unitOfWork.Complete();

var locations = unitOfWork.Location.GetAll(); // first location will be correctly loaded from the database, please see the first picture (the values are not null)

//Adding a new location and call again the GetAll(), will give 2 results now, but the second result is a EF dynamic proxy and doesn't have the FK class members loaded...

请看那些图片,第一次插入后获取数据没问题,但是第二次插入后,获取数据时会出现这种情况:

当您第一次保存位置并尝试获取所有位置时,它将正确加载到上下文中,因为您将其添加到同一上下文中, 第二次相关实体将为空,因为它是新上下文

发生这种情况是因为未启用延迟加载

 this.Configuration.LazyLoadingEnabled = false;

要获取相关项目,您应该包括它们 Check This

1-将 GetAllWithInclude 添加到您的基础 Repository

public IEnumerable<TEntity> GetAllWithInclude(List<string> includes)
{
    IQueryable<TEntity> entities = Context.Set<TEntity>();
    foreach (var include in includes)
    {
        entities = entities.Include(include);
    }
    return entities.ToList();
} 

2- 将 GetAllWithInclude 添加到 ILocationRepository 接口

IEnumerable<AffectedLocation> GetAllWithInclude(List<string> includes);

3-获取您的数据,将您要包含的子实体添加到包含列表

List<string> includes = new List<string>
{
    "RadiationLevel",
    "GeographicalCoordinates"
};

List<AffectedLocation> affectedLocations = uow.Location.GetAllWithInclude(includes).ToList();