Entity Framework 7 Accesso agli oggetti entità all'interno di ICollection

asp.net-core-mvc c# entity-framework-core

Domanda

Ho due entità utenti e indirizzi. Indirizzi è una proprietà ICollection sulle entità Users. Tuttavia non sono in grado di accedere ai singoli indirizzi all'interno di ICollection. È possibile e ho solo la sintassi sbagliata o il framework di entità non lo consente.

Il codice:

utenti:

 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; }
}

indirizzi:

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; }
}

Deposito (genitore):

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

UserRepository:

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

Il seguente codice non mi darà accesso al primo indirizzo nella proprietà ICollection sull'entità utente

[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");
    }

Si prega di avvisare su come correggere il mio codice in modo da avere accesso alle entità nella collezione.

Risposta accettata

Nel caso qualcuno si chiedesse come ho risolto questo qui è la risposta:

Come menzionato da COLD TOLD ICollection non supporta l'indicizzazione come array. Tuttavia, le liste lo fanno cambiando in una lista invece che in una ICollection e cancellato l'hashset che è stato creato nel 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; }
}

Questo mi permette di accedere a quelle entità nidificate come in questo modo:

[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");
}

Risposta popolare

Non penso sia una buona idea includere così tanti nella tua selezione che potrebbero causare problemi alle tue prestazioni, potresti provare a cambiare l'ordine della query

 return DbSet.Include(o => o.Orders)
            .Include(o => o.Addresses)
            .Where(o => o.Id == Id)
            .FirstOrDefault();


Related

Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché