まとめると、これには4つの解決策があります。
解決策1:DBContextのProxyCreationをオフにして、最後に復元します。 
    private DBEntities db = new DBEntities();//dbcontext
    public ActionResult Index()
    {
        bool proxyCreation = db.Configuration.ProxyCreationEnabled;
        try
        {
            //set ProxyCreation to false
            db.Configuration.ProxyCreationEnabled = false;
            var data = db.Products.ToList();
            return Json(data, JsonRequestBehavior.AllowGet);
        }
        catch (Exception ex)
        {
            Response.StatusCode = (int)HttpStatusCode.BadRequest;
            return Json(ex.Message);
        }
        finally
        {
            //restore ProxyCreation to its original state
            db.Configuration.ProxyCreationEnabled = proxyCreation;
        }
    }
解決策2:ReferenceLoopHandlingを設定してJsonConvertを使用し、シリアライザー設定を無視する。 
    //using using Newtonsoft.Json;
    private DBEntities db = new DBEntities();//dbcontext
    public ActionResult Index()
    {
        try
        {
            var data = db.Products.ToList();
            JsonSerializerSettings jss = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
            var result = JsonConvert.SerializeObject(data, Formatting.Indented, jss);
            return Json(result, JsonRequestBehavior.AllowGet);
        }
        catch (Exception ex)
        {
            Response.StatusCode = (int)HttpStatusCode.BadRequest;
            return Json(ex.Message);
        }
    }
以下の2つのソリューションは同じですが、強い型付けがされているため、モデルを使用する方が適しています。
解決策3:必要なプロパティのみを含むモデルを返す。
    private DBEntities db = new DBEntities();//dbcontext
    public class ProductModel
    {
        public int Product_ID { get; set;}
        public string Product_Name { get; set;}
        public double Product_Price { get; set;}
    }
    public ActionResult Index()
    {
        try
        {
            var data = db.Products.Select(p => new ProductModel
                                                {
                                                    Product_ID = p.Product_ID,
                                                    Product_Name = p.Product_Name,
                                                    Product_Price = p.Product_Price
                                                }).ToList();
            return Json(data, JsonRequestBehavior.AllowGet);
        }
        catch (Exception ex)
        {
            Response.StatusCode = (int)HttpStatusCode.BadRequest;
            return Json(ex.Message);
        }
    }
解決策4:必要なプロパティのみを含む新しい動的オブジェクトを返す。
    private DBEntities db = new DBEntities();//dbcontext
    public ActionResult Index()
    {
        try
        {
            var data = db.Products.Select(p => new
                                                {
                                                    Product_ID = p.Product_ID,
                                                    Product_Name = p.Product_Name,
                                                    Product_Price = p.Product_Price
                                                }).ToList();
            return Json(data, JsonRequestBehavior.AllowGet);
        }
        catch (Exception ex)
        {
            Response.StatusCode = (int)HttpStatusCode.BadRequest;
            return Json(ex.Message);
        }
    }
               
              
ScriptIgnore属性を使用した解決策があります。stackoverflow.com/questions/1193857/subsonic-3-0-0-2-structs-tt