Entity Framework 7 Доступ к объектам Entity внутри ICollection

У меня есть два объекта: пользователи и адреса. Addresses — это свойство ICollection сущностей Users. Однако я не могу получить доступ к отдельным адресам внутри ICollection. Возможно ли это, и у меня просто неправильный синтаксис или структура сущностей не позволяет этого.

Код:

Пользователи:

 public partial class User
{
    public User()
    {
        Addresses = new HashSet<Address>();
        Comments = new HashSet<Comment>();
        Orders = new HashSet<Order>();
        Posts = new HashSet<Post>();
    }

    public long Id { get; set; }
    public bool Active { get; set; }
    public DateTime? BirthDate { get; set; }
    public DateTime Created { get; set; }
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Password { get; set; }
    public DateTime? Updated { get; set; }
    public string Username { get; set; }
    public long? UserTypeId { get; set; }

    public virtual ICollection<Address> Addresses { get; set; }
    public virtual ICollection<Comment> Comments { get; set; }
    public virtual ICollection<Order> Orders { get; set; }
    public virtual ICollection<Post> Posts { get; set; }
    public virtual UserType UserType { get; set; }
}

Адреса:

public partial class Address
{
    public long Id { get; set; }
    public bool Active { get; set; }
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string City { get; set; }
    public DateTime Created { get; set; }
    public string State { get; set; }
    public DateTime? Updated { get; set; }
    public long? UserId { get; set; }
    public string Zip { get; set; }

    public virtual User User { get; set; }
}

Репозиторий (родительский):

public class Repository<T> where T : class
{
    private DemoContext _context;

    protected DbSet<T> DbSet;

    public Repository(DemoContext context)
    {
        _context =context;
        DbSet = _context.Set<T>();
    }

    public virtual T Get(int Id)
    {
        // TODO: Implement with return of DbSet.Find();

        // DbSet.Find(Id);
        return null;
    }

    public virtual List<T> GetAll()
    {
        return DbSet.ToList();
    }

    public virtual void Add(T entity)
    {
        DbSet.Add(entity);
    }

    public virtual void Update(T user)
    {
        _context.Entry<T>(user)
            .State = EntityState.Modified;
    }

    public virtual void SaveChanges()
    {
        _context.SaveChanges();
    }

    public virtual void Delete(int Id)
    {
        // TODO: Implement with return of DbSet.Find();

        // DbSet.Remove(Dbset.Find(Id));
    }

Пользовательский репозиторий:

 public class UserRepository : Repository<User>
{
    public UserRepository(DemoContext context)
        : base(context)
    {

    }

    public override User Get(int Id)
    {
        return DbSet
            .Where(o => o.Id == Id)
            .Include(o => o.Orders)
            .Include(o => o.Addresses)
            .ToList()
            .Single();
    }

    public override List<User> GetAll()
    {
        return DbSet
            .Include(o => o.Orders)
            .Include(o => o.Addresses)
            .ToList();
    }

    public override void Delete(int Id)
    {     
        DbSet.Remove(Get(Id));
    }
}

Следующий код не даст мне доступ к первому адресу в свойстве ICollection в объекте пользователя.

[HttpGet("[action]")]
    public IActionResult Create()
    {
        var user = userRepository.Get(1);

        var order = new Order
        {
            Address = user.Addresses[0].Address,
            City = user.Addresses[0].City,
            State = user.Addresses[0].State,
            Zip = user.Addresses[0].Zip,
            User = user,
            SubTotal = 100,
            Tax = 25,
            Total = 125
        };

        orderRepository.Add(order);
        orderRepository.SaveChanges();

        return RedirectToAction("Index");
    }

Пожалуйста, сообщите, как исправить мой код, чтобы у меня был доступ к объектам в коллекции.


person Dblock247    schedule 14.01.2016    source источник
comment
Вы получаете исключение или ноль в адресах?   -  person lazy    schedule 14.01.2016
comment
Ошибка: невозможно применить индексирование с помощью [] к выражению типа ICollection‹Addresses›   -  person Dblock247    schedule 14.01.2016
comment
Попробуйте user.addresses.first().adress   -  person lazy    schedule 15.01.2016


Ответы (2)


На всякий случай, если кому-то было интересно, как я решил это, вот ответ:

Как уже упоминалось COLD TOLD ICollection не поддерживает индексацию массива. Однако списки меняют его на список вместо ICollection и удаляют хэш-набор, созданный в custructor.

 public partial class User
{
    public User()
    {
    }

    public long Id { get; set; }
    public bool Active { get; set; }
    public DateTime? BirthDate { get; set; }
    public DateTime Created { get; set; }
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Password { get; set; }
    public DateTime? Updated { get; set; }
    public string Username { get; set; }
    public long? UserTypeId { get; set; }

    public virtual List<Address> Addresses { get; set; }
    public virtual List<Comment> Comments { get; set; }
    public virtual List<Order> Orders { get; set; }
    public virtual List<Post> Posts { get; set; }
    public virtual UserType UserType { get; set; }
}

Это позволяет мне получить доступ к этим вложенным объектам следующим образом:

[HttpGet("/")]
public IActionResult Create()
{
    var user = userRepository.Get(1);

    var order = new Order
    {
        Address = user.Addresses[0].Address1,
        City = user.Addresses[0].City,
        State = user.Addresses[0].State,
        Zip = user.Addresses[0].Zip,
        User = user,
        SubTotal = 100,
        Tax = 25,
        Total = 125
    };

    orderRepository.Add(order);
    orderRepository.SaveChanges();

    return RedirectToAction("Index");
}
person Dblock247    schedule 15.01.2016

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

 return DbSet.Include(o => o.Orders)
            .Include(o => o.Addresses)
            .Where(o => o.Id == Id)
            .FirstOrDefault();
person COLD TOLD    schedule 14.01.2016
comment
Спасибо за ответ, но это, похоже, не сработало для меня. Я получаю следующую ошибку: невозможно применить индексирование с помощью [] к выражению типа ICollection‹Addresses› - person Dblock247; 14.01.2016
comment
может быть, потому что коллекция не поддерживает массивы, такие как индексация - person COLD TOLD; 14.01.2016
comment
как индексировать коллекцию? - person Dblock247; 14.01.2016
comment
вы можете попробовать user.Addresses.ToArray()[0].Address,; - person COLD TOLD; 14.01.2016