Identity Membership i EF 6 dane z bazy nie są "mapowane" na obiekt użytkownika

0

Cześć, piszę sobie prosty sklep internetowy w MVC 5, używam Identity do obsługi użytkowników. Dodałem parę pół do klasy użytkownika by można było uzupełnić dane adresowe oraz przeglądać historie zakupionych produktów.

Tak wygląda klasa użytkownika:

 namespace WebUI.Models
{
    // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
    public class ApplicationUser : IdentityUser
    {
        public ApplicationUser()
        {
            Purchases = new List<Purchase>();
        }
        public string Email { get; set; }
        public List<Purchase> Purchases { get; set; }

        public string Country { get; set; }
        public string City { get; set; }
        public string Street { get; set; }
        public string PostalCode { get; set; }
        public string HouseNumber { get; set; }
    }

    public class Purchase
    {
        public int Id { get; set; }
        public IList<CartItem> CartItems { get; set; }
        public System.DateTime Date { get; set; }
        public virtual ApplicationUser ApplicationUser { get; set; }
    }
    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("Users")
        {
            Database.SetInitializer<ApplicationDbContext>(new DropCreateDatabaseIfModelChanges<ApplicationDbContext>());
        }
    }
}

Udaje mi się dodawać produkty do karty i wykonać akcję zakupu, rekord jest tworzony w bazie, jednak mam problem potem się do tych danych "dobrać".

Kod metod finalizującej zakup oraz wyświetlającej historie zakupów:

        public ActionResult FinalizeShopping()
        {
            var user = UserManager.FindById(User.Identity.GetUserId());
            Cart c = (Cart)TempData["cart"];
            user.Purchases.Add(new Purchase() { CartItems = c.CollectionCartItems.ToList(), Date = DateTime.Now });
            UserManager.Update(user);
            c.Clear();
            return View();
        }

        public ActionResult DisplayShoppingHistory()
        {
            var user = UserManager.FindById(User.Identity.GetUserId());
            UserManager.Update(user);
            return View(user.Purchases);
        } 

W kontrolerze obsługującym kartę obsługuję akcję zakupu w taki sposób, że zapisuję dane o zawartości karty w sesji i przekierowuję akcję do AccountControllera:

         public ActionResult Purchase()
        {
            Cart c = GetCart();
            TempData["Cart"] = c;
            return RedirectToAction("FinalizeShopping", "Account");
        }

Używam takiej metody

UserManager.Update(user); 

by "zaaktualizowac dane w bazie względem danych w programie", sam nie wiem czy to na takiej zasadzie działa jak mi się wydaje.

Co zrobić by móc swobodnie odczytywać dane z bazy?

Pozdrawiam.

0

Nie wiem czy dokładnie wyjaśniłem z czym jest problem, w tej metodzie:

public ActionResult DisplayShoppingHistory()
        {
            var user = UserManager.FindById(User.Identity.GetUserId());
            UserManager.Update(user);
            return View(user.Purchases);
        }  

Purchases jest listą, podczas debugowania sprawdzam jej właściwości, ilość elementów wynosi 0 mimo że udało się wcześniej coś do tej listy dodać/zapisać w bazie.

0

Prawdopodobnie chodzi o to że Entity Framework nie wypełnia tej listy jeśli nie dasz Include. Jestem newbie w MVC i nie wiem jak "kazać" UserManager'owi to zrobić, ja mam to inaczej zaprojektowane i nie mam tego problemu.
http://msdn.microsoft.com/pl-pl/data/jj574232.aspx

0
Świetny Samiec napisał(a):

Purchases jest listą, podczas debugowania sprawdzam jej właściwości, ilość elementów wynosi 0 mimo że udało się wcześniej coś do tej listy dodać/zapisać w bazie.

Jesteś pewien, czy dane są zapisane w bazie?
Jesteś pewien, że mają ustawione poprawne wartości w kolumnie wiążącej zakup z użytkownikiem?
Czy zapis był dokonywany przez EF czy bezpośrednio w bazie?
Jeśli przez EF, to czy przez ten sam kontekst?

0
somekind napisał(a):
Świetny Samiec napisał(a):

Purchases jest listą, podczas debugowania sprawdzam jej właściwości, ilość elementów wynosi 0 mimo że udało się wcześniej coś do tej listy dodać/zapisać w bazie.

Jesteś pewien, czy dane są zapisane w bazie?
Jesteś pewien, że mają ustawione poprawne wartości w kolumnie wiążącej zakup z użytkownikiem?
Czy zapis był dokonywany przez EF czy bezpośrednio w bazie?
Jeśli przez EF, to czy przez ten sam kontekst?

Tak, dane sa zapisywane w bazie, są poprawnie wiązane, udało mi się wczytać Purchases robiąc taką zmianę w kontekście

 public ApplicationDbContext()
            : base("Users")
        {
            Database.SetInitializer<ApplicationDbContext>(new DropCreateDatabaseIfModelChanges<ApplicationDbContext>());
            this.Users.Include("Purchases.CartItems").ToListAsync();
            
        }

Purchases zawiera CartItems, to też się wczytuje, ale Produkt który zawarty jest w CartItem już się poprawnie nie ładuje i w jego miejscu jest null.

CartItem składa się z pola ID, z pola oznaczającego ilość i z pola Produkt typu Produkt, id i ilość są poprawne a pordukt jest nullem.

Zapis jest widoczny w metodzie FinalizeShopping.

0

Ooook, działa. Tak to wczytałem:

 public ApplicationDbContext()
            : base("Users")
        {
            Database.SetInitializer<ApplicationDbContext>(new DropCreateDatabaseIfModelChanges<ApplicationDbContext>());

            foreach (var user in Users)
            {
                this.Entry(user).Collection(x=>x.Purchases).Load();
                foreach (var purchase in user.Purchases)
                {
                    this.Entry(purchase).Collection(x => x.CartItems).Load();
                    foreach (var cartItem in purchase.CartItems)
                    {
                        this.Entry(cartItem).Reference(x => x.Product).Load();
                    }
                }
            }           
        }
    }

Widzę że warto by zgłębić temat Entity Framework dokładniej a nie tak jak ja - po łebkach, bo potem się człowiek gubi.
Czy tak jak to mam jest dobrze? Wczytuje mi to wszystko od razu, czy takie rozwiązanie w "dużych" projektach jest dopuszczalne?

Pozdrawiam

0

A ile zapytań do bazy generuje ten kod?

0

Czy to nie jest tak że to od razu na wejściu ładuje prawie całą bazę do pomięci?

0

No dobra, tak myślałem że to nie jest dobrze. Jak w takim razie to zrobić żeby miało ręce i nogi?

1 użytkowników online, w tym zalogowanych: 0, gości: 1