I have a very strange problem. I followed an MVC tutorial.
I have an interface:
namespace DomainModel.Abstract
{
public interface IProductsRepository
{
IQueryable<Product> Products { get; }
}
}
A repository inherits that interface:
namespace DomainModel.Concrete
{
public class SqlProductsRepository : IProductsRepository
{
private Table<Product> productsTable;
public SqlProductsRepository(string connectionString)
{
try
{
productsTable = (new DataContext(connectionString)).GetTable<Product>();
}
catch (Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
}
}
public IQueryable<Product> Products
{
get { return productsTable; }
}
}
}
My Product class looks like this:
namespace DomainModel.Entities
{
[Table(Name = "Products")]
public class Product
{
[Column(IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
public int ProductID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}
}
And my controller looks like this:
namespace WebUI.Controllers
{
public class ProductsController : Controller
{
private IProductsRepository productsRepository;
public ProductsController()
{
string connString = #"Data Source=INFO_KW-HZ7YX91;Initial Catalog=SportStore;Integrated Security=True";
productsRepository = new SqlProductsRepository(connString);
}
public ViewResult List()
{
return View(productsRepository.Products.ToList());
}
}
}
My Products table has 8 rows. When I run the web site, It displays 8 rows but they are all blanks and zero. When I debugged it, I can see productsTable has 8 rows with correct column names, but the string data are null and the integer data are zero.
What did I do wrong?
Thanks
It has been quite a while since last time I did custom attributes like this, but I guess you need to put [Column] for all properties you need to persist. Something like:
[Column]
public string Name { get; set; }
[Column]
public string Description { get; set; }
[Column]
public string Category { get; set; }
[Column]
public decimal Price { get; set; }
assuming that your sql table field names match the property names accordingly.
You didn't add [Column] attributes to any of your columns but your PK. LinqToSql is very attribute heavy, and hand-coding the classes will be fraught with risk and (most likely) frightening exceptions. You should use sqlmetal.exe or your own generator.
Related
Using an example, I have the following two Entities. The OrderEntity contains a collection of OrderLineEntites
public class OrderEntity
{
public string Reference { get; set; }
public string Description { get; set; }
public bool Confirmed { get; set; }
[NotMapped]
public int OrderLineCount { get; set; }
[InverseProperty("Order")]
public virtual ICollection<OrderLineEntity> OrderLineEntity__OrderEntity { get; set; }
}
public class OrderLineEntity
{
public string Name { get; set; }
public string Description { get; set; }
}
Using the following code I can load all the OrderLineEntities for all confirmed orders.
DbSet<OrderEntity> orderEntity.Where(x => x.Confirmed).Include(x => x.OrderLineEntity__OrderEntity)
What I need to do is set the non-mapped OrderLineCount property with the Count of the OrderLine records (to save actually loading them).
So for each loaded Order I have a fully populated Entity including the [NotMapped] property with an empty OrderLine collection.
Advise would be appreciated :)
Thanks
You can do this, but you have to change your approach. You have to manually map the objects yourself:
var query = from a in context.Orders.Where(x => x.Confirmed)
select new OrderEntity
{
Reference = a.Reference,
Description = a.Description,
Confirmed = a.Confirmed,
OrderLineCount = a.OrderLineEntity__OrderEntity.Count
};
return query.ToList();
By default, Controller.Json generates JSON for each public member of a class. How can I change this so that some members are ignored. Please note that I am using .Net Core.
Example:
[HttpGet("/api/episodes")]
public IActionResult GetEpisodes()
{
var episodes = _podcastProvider.Get();
return Json(episodes);
}
Thanks.
You can use [JsonIgnore] attribute that available in Newtonsoft.Json namespace like below:
public class Model
{
public int Id { get; set; }
public string Name { get; set; }
[JsonIgnore]
public int Age { get; set; }
}
How can I change this so that some members are ignored?
Under the covers this uses Newtonsoft.Json. There are two ways you can do this.
Use the JsonIgnore attribute and mark the properties you want omitted.
Have your episodes class define itself as "opt-in", meaning only properties marked with JsonProperty are serialized. [JsonObject(MemberSerialization.OptIn)]
It depends on the number of properties you need omitted versus serialized.
public class Episode
{
public int Id { get; }
[JsonIgnore] public string Name { get; }
[JsonIgnore] public Uri Uri { get; }
[JsonIgnore] public long Length { get; }
}
The above will yield the same JSON as this:
[JsonObject(MemberSerialization.OptIn)]
public class Episode
{
[JsonProperty]
public int Id { get; }
public string Name { get; }
public Uri Uri { get; }
public long Length { get; }
}
I got two simple entities:
public class Ingredient : IEntity
{
public Ingredient()
{
Drinks = new List<Drink>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Drink> Drinks { get; set; }
}
public class Drink : IEntity
{
public Drink()
{
Ingridients = new List<Ingredient>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Ingredient> Ingridients { get; set; }
public string Approach { get; set; }
}
I get the following error:
Object graph for type 'Gudo.Core.Model.Ingredient' contains cycles and cannot be serialized if reference tracking is disabled.
I've tried using the JsonIgnore Attribute on the Drinks collection and I've tried using:
JsonSerializerSettings jsSettings = new JsonSerializerSettings();
jsSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
In my global.asax
Nothing works..
Please help.
Did you make sure to set this on the JSON formatter's serializer settings? This line should do it for you:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
Using jqGrid in mvc razor
I want a class that can go for jqGrid json format and bind the grid.
I think that you don't need to define any class to produce JSON data needed for jqGrid. You can return anonymous object:
public JsonResult DynamicGridData (string sidx, string sord, int page, int rows)
{
var query = ...;
var totalRecords = query.Count();
return Json(new {
total = (totalRecords + rows - 1) / rows,
page,
records = totalRecords,
rows = (from item in query
select new {
id = item.Id.ToString(),
cell = new[] {
item.FirstName,
item.LastName,
item.Votes.ToString(),
item.Title
}
}).ToList()
},
JsonRequestBehavior.AllowGet);
}
Firstly this is the wrong way of asking question at Stackoverflow.com please read Faq and whathaveyoutried.com
But since you are new to Stackoverflow I will answer this one for you,
public class JqGridModel<T>
{
public int page { get; set; }
public Int32? total { get; set; }
public Double? records { get; set; }
public IEnumerable<T> GridData { get; set; }
public JqGridModel<T> Bind(IEnumerable<T> data)
{
records = data.Count();
GridData = data;
page = 1;
return this;
}
}
also from your comments you said,
actually i am trying to use jqgrid with mvc razor and entity framework.
I recommend you go through this article once, it might be helpful. Here too a jqGrid class is defined as... the above one is more generic though, but it all depends on your use case.
public class JqGridObject
{
public string Page { get; set; }
public int PageSize { get; set; }
public string SortColumn { get; set; }
public string SortOrder { get; set; }
public List<Fruit> Data { get; set; }
}
public class Fruit
{
public int Id { get; set; }
public string Name { get; set; }
}
When I call context.SaveChanges() to update a specific product, the update is not registered in the database. I do not get any runtime error either. All I notice is that my product catalog is not updated. I still see the same values. When I run the debugger I notice that the connection state of the database is closed.
This is the class implementing the context.SaveChanges()
namespace SportsStore.Domain.Concrete
{
public class EFProductRepository : IProductRepository
{
private EFDbContext context = new EFDbContext();
public IQueryable<Product> Products
{
get { return context.Products; }
}
public void SaveProduct(Product product)
{
if (product.ProductID == 0)
{
context.Products.Add(product);
}
context.SaveChanges();
}
}
}
namespace SportsStore.Domain.Concrete
{
public class EFDbContext : DbContext
{
public DbSet<Product> Products { get; set; }
}
}
namespace SportsStore.Domain.Entities
{
public class Product
{
[HiddenInput(DisplayValue=false)]
public int ProductID { get; set; }
public string Name { get; set; }
[DataType(DataType.MultilineText)]
public string Description { get; set; }
public string Category { get; set; }
public decimal Price { get; set; }
}
}
In the EFProductRepository class, prior to calling the context.SaveChanges() method in the SaveProduct method, you can use one of the following approaches to persist changes to the database.
public void SaveProduct(Product product)
{
if (product.ProductID == 0)
{
context.Products.Add(product);
}
//One approach to persist changes to database
//var productInDB = context.Products.Single(x => x.ProductID ==product.ProductID);
//context.Entry(productInDB).CurrentValues.SetValues(product);
//context.SaveChanges();
//Alternate Approach
if (product.ProductID != 0)
{
context.Entry(product).State = System.Data.EntityState.Modified;
}
context.SaveChanges();
}