Entity Framework с кодом, сначала не инициализирующим член класса Foreign Key - PullRequest
0 голосов
/ 29 декабря 2018

Я использую EF 6, сначала с кодом, и у меня есть класс модели предметной области, который имеет 2 FK и связанные объекты в качестве членов класса.Вставка работает нормально, но когда дело доходит до получения значений из базы данных, объекты FK, связанные с этим объектом, являются нулевыми.

Я попытался установить для параметра Lazy Initialization значение false и пометить членов класса FK как виртуальных.Я попробовал 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...

Пожалуйста, посмотрите на эти фотографии, получите данные после первой вставки, но все в порядке, нопосле второй вставки, при получении данных это произойдет:

two muppets two muppets

1 Ответ

0 голосов
/ 30 декабря 2018

Когда вы сохраняете местоположение в первый раз и пытаетесь получить все местоположения, оно будет правильно загружено в контексте, потому что вы добавляете его в тот же контекст, объекты, связанные со вторым разом, будут нулевыми, потому что это новый контекст

Это происходит потому, что Ленивая загрузка не включена

 this.Configuration.LazyLoadingEnabled = false;

Чтобы получить связанные элементы, вы должны включить их Отметьте это

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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...