Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework do not load related objects

I'm developing the Music Store sample app with ASP.NET MVC, Entity Framework and WCF.

This is a layered application which has a common layer for the entities.

in the AddToCart Action method , the Album object is populates fine but after the Cart save when wcf loads the cart object the associated Album object is Null, may be some serialization issue (I have not idea), in the view @foreach (var item in Model.CartItems) the item.Album.Title becomes null

This is my code:

public static void AddToCart(Album album, string ShoppingCartID)
{
            using (MusicStoreEntities db = new MusicStoreEntities())
            {
                // Get the matching cart and album instances
                var cartItem = db.Carts.SingleOrDefault(
                    c => c.CartId == ShoppingCartID
                         && c.AlbumId == album.AlbumId);

                if (cartItem == null)
                {
                    // Create a new cart item if no cart item exists
                    cartItem = new Cart
                    {
                        AlbumId = album.AlbumId,
                        CartId = ShoppingCartID,
                        Count = 1,
                        DateCreated = DateTime.Now                           
                    };

                    db.Carts.Add(cartItem);
                }
                else
                {
                    // If the item does exist in the cart, then add one to the quantity
                    cartItem.Count++;
                }

                // Save changes
                db.SaveChanges();
            }
}

public static List<Cart> GetCartItems(string ShoppingCartID)
        {
            using (MusicStoreEntities db = new MusicStoreEntities())
            {
               return db.Carts.Where(cart => cart.CartId == ShoppingCartID).ToList();

            }
        }

Controller

namespace MusicStore.Web.Controllers
{
    public class ShoppingCartController : Controller
    {
        MusicShoppingCartMgr.Cart serviceref1 = new MusicShoppingCartMgr.Cart();
        MusicShoppingCartMgr.iShoppingCart servicemethodref1 = new iShoppingCartClient();
        //
        // GET: /ShoppingCart/
        public ActionResult Index()
        {
            var cart = ShoppingCart.GetCart(this.HttpContext);

            // Set up our ViewModel
            var viewModel = new ShoppingCartViewModel
            {
                CartItems = cart.GetCartItems(cart.ShoppingCartId),
                CartTotal = cart.GetTotal(cart.ShoppingCartId)
            };

            // Return the view
            return View(viewModel);
        }
        //
        // GET: /Store/AddToCart/5

        public ActionResult AddToCart(int id)
        {
            var addedAlbum = servicemethodref1.GetAlbum(id);

            // Add it to the shopping cart
            var cart = ShoppingCart.GetCart(this.HttpContext);

            cart.AddToCart(addedAlbum, cart.ShoppingCartId);

            // Go back to the main store page for more shopping
            return RedirectToAction("Index");
        }


    }
}

Model Classes

namespace MusicStore.Core
{
    [Serializable]
    [DataContract]
    public class Cart
    {
        [Key]
        [DataMember]
        public int RecordId { get; set; }
        [DataMember]
        public string CartId { get; set; }
        [DataMember]
        public int AlbumId { get; set; }
        [DataMember]
        public int Count { get; set; }
        [DataMember]
        public System.DateTime DateCreated { get; set; }
        [DataMember]
        public virtual Album Album { get; set; }
    }
}

namespace MusicStore.Core
{
    [Serializable]
    [DataContract]
    //[Bind(Exclude = "AlbumId")]
    public class Album
    {
        [DataMember]
        [ScaffoldColumn(false)]
        public int AlbumId { get; set; }

        [DataMember]
        [DisplayName("Genre")]
        public int GenreId { get; set; }

        [DataMember]
        [DisplayName("Artist")]
        public int ArtistId { get; set; }

         [DataMember]
        [Required(ErrorMessage = "An Album Title is required")]
        [StringLength(160)]
        public string Title { get; set; }

         [DataMember]
        [Required(ErrorMessage = "Price is required")]
        [Range(0.01, 100.00,
            ErrorMessage = "Price must be between 0.01 and 100.00")]
        public decimal Price { get; set; }

         [DataMember]
        [DisplayName("Album Art URL")]
        [StringLength(1024)]
        public string AlbumArtUrl { get; set; }

           [DataMember]
         public virtual Genre Genre { get; set; }
           [DataMember]
        public virtual Artist Artist { get; set; }
         public virtual List<OrderDetail> OrderDetails { get; set; }
    }
}

DB Context

namespace MusicStore.Data
{
    public class MusicStoreEntities : DbContext
    {
        public MusicStoreEntities()
            : base("MusicStoreEntities")
        {
            var ensureDLLIsCopied = System.Data.Entity.SqlServer.SqlProviderServices.Instance;

            this.Configuration.ProxyCreationEnabled = false;

            Database.SetInitializer<MusicStoreEntities>(new CreateDatabaseIfNotExists<MusicStoreEntities>());
            Database.SetInitializer(new CommonDBInitializer());
        }

        public DbSet<Album> Albums { get; set; }
        public DbSet<Genre> Genres { get; set; }
        public DbSet<Artist> Artists { get; set; }
        public DbSet<Cart> Carts { get; set; }
        public DbSet<Order> Orders { get; set; }
        public DbSet<OrderDetail> OrderDetails { get; set; }
    }
}

Question is: why it is the Album object is not loaded inside Cart object, and how to fix it?

like image 727
Sanjeewa Avatar asked Jan 28 '23 23:01

Sanjeewa


1 Answers

Entity Framework does not load related objects by default to help prevent potential performance problems around loading one-to-many or many-to-many relationships into memory.

Looking at the code you have posted, it seems a potential fix would be for you to add .Include("Album") when getting out the cart items in GetCartItems. It would then become

public static List<Cart> GetCartItems(string ShoppingCartID)
{
    using (MusicStoreEntities db = new MusicStoreEntities())
    {
        return db.Carts.Include("Album").Where(cart => cart.CartId == ShoppingCartID).ToList();
    }
}

See the Entity Framework docs for some other options around loading related entities

like image 140
sedders123 Avatar answered Jan 30 '23 14:01

sedders123