I created entity in database using code first, which mostly refers to the dictionary tables:
public class Item
{
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public Material Material { get; set; }
public int MaterialId { get; set; }
public Supplier Supplier { get; set; }
public int SupplierId { get; set; }
public Charact Charact { get; set; }
public int CharactId { get; set; }
public ItemType ItemType { get; set; }
public int ItemTypeId { get; set; }
public Size Size { get; set; }
public int SizeId { get; set; }
public int GroupId { get; set; }
public Group Group { get; set; }
public string Number { get; set; }
public string DescriptionSum { get; set; }
}
All dictionary models have similar properties, where property 'No' is key property in this case and is one or two character string:
public class Size
{
public int Id { get; set; }
public string Name { get; set; }
public string No { get; set; }
}
While creating new Item, user will select one record from each all avaliable in dictionary tables and save them in the Item table:
ItemsController for Create:
// GET: Items/Create
public IActionResult Create(int? gr)
{
ViewData["CharactId"] = new SelectList(_context.Charact, "Id", "Name");
ViewData["GroupId"] = new SelectList(_context.Group, "Id", "Name");
ViewData["ItemTypeId"] = new SelectList(_context.ItemType.Where(ItemType => ItemType.GroupId == gr), "Id", "Name");
ViewData["MaterialId"] = new SelectList(_context.Materials, "Id", "Name");
ViewData["SizeId"] = new SelectList(_context.Size, "Id", "Name");
ViewData["SupplierId"] = new SelectList(_context.Supplier.Where(Supplier => Supplier.GroupId == gr), "Id", "Name");
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Name,Description,MaterialId,SupplierId,CharactId,ItemTypeId,SizeId,GroupId,Number,DescriptionSum")] Item item)
{
if (ModelState.IsValid)
{
_context.Add(item);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["CharactId"] = new SelectList(_context.Charact, "Id", "Name", item.CharactId);
ViewData["GroupId"] = new SelectList(_context.Group, "Id", "Name", item.GroupId);
ViewData["ItemTypeId"] = new SelectList(_context.ItemType, "Id", "Name", item.ItemTypeId);
ViewData["MaterialId"] = new SelectList(_context.Materials, "Id", "Name", item.MaterialId);
ViewData["SizeId"] = new SelectList(_context.Size, "Id", "Name", item.SizeId);
ViewData["SupplierId"] = new SelectList(_context.Supplier, "Id", "Name", item.SupplierId);
return View(item);
}
What I am trying to do is to "automatically" populate Number property, accordingly to selected in form options, based on 'No' properties and save it in database:
Number = Group.No + Supplier.No + ItemType.No + Charact.No + Material.No + Size.No;
Concatenated number would define chosen configuration of options. Because the same "No" can occure multiple times in the same table, it cannot be used as identification column.
I have tried few approaches, which I found in web:
Updating ItemController:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult>Create([Bind("Id,Name,Description,MaterialId,SupplierId,CharactId,ItemTypeId,SizeId,GroupId,Number,DescriptionSum")] Item item)
{
if (ModelState.IsValid)
{
item.Number = item.Group.No + item.Supplier.No + item.ItemType.No + item.Charact.No + item.Material.No + item.Size.No;
_context.Add(item);
await _context.SaveChangesAsync();
}
ViewData["CharactId"] = new SelectList(_context.Charact, "Id", "Name", item.CharactId);
ViewData["GroupId"] = new SelectList(_context.Group, "Id", "Name", item.GroupId);
ViewData["ItemTypeId"] = new SelectList(_context.ItemType, "Id", "Name", item.ItemTypeId);
ViewData["MaterialId"] = new SelectList(_context.Materials, "Id", "Name", item.MaterialId);
ViewData["SizeId"] = new SelectList(_context.Size, "Id", "Name", item.SizeId);
ViewData["SupplierId"] = new SelectList(_context.Supplier, "Id", "Name", item.SupplierId);
return View(item);
}
Exception occurred:
An unhandled exception occurred while processing the request.
NullReferenceException: Object reference not set to an instance of an object.
Database.Controllers.ItemsController.Create(Item item) in ItemsController.cs
item.Number = item.Group.No + item.Supplier.No + item.ItemType.No + item.Charact.No + item.Material.No + item.Size.No;
Changed model:
public class Item
{
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public Material Material { get; set; }
public int MaterialId { get; set; }
public Supplier Supplier { get; set; }
public int SupplierId { get; set; }
public Charact Charact { get; set; }
public int CharactId { get; set; }
public ItemType ItemType { get; set; }
public int ItemTypeId { get; set; }
public Size Size { get; set; }
public int SizeId { get; set; }
public int GroupId { get; set; }
public Group Group { get; set; }
public string Number
{ get
{
return this.Number = this.Group.No + this.Supplier.No + this.ItemType.No + this.Charact.No + this.Material.No + this.Size.No;
}
private set { }
}
public string DescriptionSum { get; set; }
}
Same Exception but concerning line
public string Number { get { return this.Number = this.Group.No + this.Supplier.No + this.ItemType.No + this.Charact.No + this.Material.No + this.Size.No; } private set { } }
in Item model.
Other model change:
public class Item
{
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public Material Material { get; set; }
public int MaterialId { get; set; }
public Supplier Supplier { get; set; }
public int SupplierId { get; set; }
public Charact Charact { get; set; }
public int CharactId { get; set; }
public ItemType ItemType { get; set; }
public int ItemTypeId { get; set; }
public Size Size { get; set; }
public int SizeId { get; set; }
public int GroupId { get; set; }
public Group Group { get; set; }
private string _value;
public string Number { get { return _value; } private set {_value = this.Group.No + this.Supplier.No + this.ItemType.No + this.Charact.No + this.Material.No + this.Size.No; } }
public string DescriptionSum { get; set; }
}
still same exception in line:
public string Number { get { return _value; } private set {_value = this.Group.No + this.Supplier.No + this.ItemType.No + this.Charact.No + this.Material.No + this.Size.No; } }
I couldn't find any other solutions. Please help.
BR
When you create instance of Item class; The material class & The Charact is class null. So when you try to access the Number it will throw object reference as Navigation Properties are null.
Option 1 Check Null and Assign the variable.
public string Number
{
get { return _value; }
private set {_value = this.Group?.No + this.Supplier?.No + this.ItemType?.No +
this.Charact?.No + this.Material?.No + this.Size?.No; }
}
If your using C# 6 or greater you can use this Null-Conditional Operators
Option 2 Fill the Navigation object with data.
public class Item
{
//YourProperties Here
public Item()
{
this.Material = new Material();
this.Charact = new Charact();
}
}
Basically you need to data to assign data to navigation property then it would work with your same code.
At first I'm sorry for using my native language in Code, but it's my University project and our project Leader ordered us to write like this.
I'm working on Database project using Entity Framework and C#.
In short, I've created class named "Osoba" and "Klient" class which inherits from "Osoba".
Problem is that when I'm trying to add new "Klient" to database I'm still getting error as following:
System.Data.Entity.Infrastructure.DbUpdateException: „An error occurred while updating the entries. See the inner exception for details.”
SqlException: Cannot insert explicit value for identity column in table 'Klient' when IDENTITY_INSERT is set to OFF.
I've researched similar problems in web, but all of them were appearing because of "hard-coding" ID while adding new object to table.. and I'm actually not doing this.
Here is Osoba class:
[Table("Osoba")]
public class Osoba
{
public int ID { get; set; }
public string Imie { get; set; }
public string Nazwisko { get; set; }
public string Telefon { get; set; }
public string Adres { get; set; }
public string Mail { get; set; }
public int IloscTransakcji { get; set; }
public string Typ { get; set; }
public override string ToString()
{
return "Imie: " + Imie + "\t Nazwisko: " + Nazwisko + "\t Adres: " + Adres;
}
}
Klient class:
[Table("Klient")]
public class Klient: Osoba
{
public int ID { get; set; }
public string Pracownik { get; set; }
public int Sprzedane { get; set; }
public int Kupione { get; set; }
public string Preferencje { get; set; }
public override string ToString()
{
return "Obslugujacy pracownik: " + Pracownik + "\t Sprzedane: " + Sprzedane.ToString() + "\t Kupione: " + Kupione.ToString();
}
}
My Database Context:
public class BazyDanychContext : DbContext
{
public BazyDanychContext() : base("ProjektBD8")
{
}
public DbSet<Osoba> Osoba { get; set; }
public DbSet<Klient> Klient { get; set; }
public DbSet<Pracownik> Pracownik { get; set; }
public DbSet<Nieruchomosc> Nieruchomosc { get; set; }
public DbSet<Biuro> Biuro { get; set; }
public DbSet<Dom> Dom { get; set; }
public DbSet<Grunt> Grunt { get; set; }
public DbSet<Hala> Hala { get; set; }
public DbSet<Mieszkanie> Mieszkanie { get; set; }
public DbSet<Spotkanie> Spotkanie { get; set; }
public DbSet<Umowa> Umowa { get; set; }
}
And finally here is how I'm adding new Klient to database:
private void KlientAdd_Click(object sender, RoutedEventArgs e)
{
using (var ctx = new BazyDanychContext())
{
Klient tmp = new Klient { Imie = KlientImie.Text, Nazwisko = KlientNazwisko.Text, Telefon = KlientTelefon.Text, Adres = KlientAdres.Text, Mail = KlientMail.Text, IloscTransakcji = Int32.Parse(KlientIloscTransakcji.Text), Typ = "Klient" , Pracownik = KlientPracownik.Text, Sprzedane = Int32.Parse(KlientSprzedane.Text), Kupione = Int32.Parse(KlientKupione.Text), Preferencje = KlientPreferencje.Text };
ctx.Osoba.Add(tmp);
ctx.SaveChanges();
}
InitTabs();
}
So, final solution for me was removing all migrations in my project. After dropping my Database, removing all migrations and then recreate Database without any migrations in my project it finally worked. Thank you for all your suggestions.
I'm trying to get some data from to Lists using Linq. If I use join with equals using one field in each list it's ok and returns number of records as expected, but if I try use join on pair of fields it returns 0 records. Why?
List<Result> inner_join =
(from egais in rests_egais
//join best in rests_best on egais.Product.AlcCode equals best.Product.AlcCode
join best in rests_best
on new {key1 = egais.Shop, key2 = egais.Product.AlcCode}
equals new { key1 = best.Shop, key2 = best.Product.AlcCode }
where egais.Quantity != best.Quantity
select new Result
{
Shop = egais.Shop,
AlcCode = egais.Product.AlcCode,
FullName = egais.Product.FullName,
Quantity_Egais = egais.Quantity,
Quantity_Best = best.Quantity,
Difference = best.Quantity - egais.Quantity
}).ToList();
EDITED: These are classes to use:
public class Rest
{
public Rest()
{
Product = new Product();
}
public string Shop { get; set; }
public DateTime Date { get; set; }
public double Quantity { get; set; }
public string InformF1RegId { get; set; }
public string InformF2RegId { get; set; }
public Product Product { get; set; }
}
public class Product
{
public Product()
{
Producer = new Producer();
}
public string FullName { get; set; }
public string AlcCode { get; set; }
public double Capacity { get; set; }
public string UnitType { get; set; }
public double AlcVolume { get; set; }
public int ProductVCode { get; set; }
public Producer Producer { get; set; }
}
public class Producer
{
public string ClientRegId { get; set; }
public string FullName { get; set; }
public string ShortName { get; set; }
public int Country { get; set; }
public string Description { get; set; }
}
public class Result
{
public string Shop { get; set; }
public string AlcCode { get; set; }
public string FullName { get; set; }
public double Quantity_Egais { get; set; }
public double Quantity_Best { get; set; }
public double Difference { get; set; }
}
I have a ViewModel shown below.
For each RateList - it can have a number of Occ objects linked to it.
What I'm trying to do in Occs.occval is to return a concatenated string which takes TypeName from the parent RatesList model, and concatenates it to the occdesk property in the Occ = ie. return occdesc + "||" + RatesList.TypeName; but I get the error: Object reference not set to an instance of an object.
Is there any way to achieve this in the model below?
Thank you,
Mark
public class RatesList
{
public long Id { get; set; }
public string TypeName { get; set; }
public string TypeDesc { get; set; }
public int TypeCount { get; set; }
public virtual IQueryable<Occ> Occs { get; set; }
public string OccSelected { get; set; }
}
public class Occ
{
public string occdesc { get; set; }
public string occval {
get
{
return occdesc + "||" + RatesList.TypeName;
}
}
public int numOfOcc { get; set; }
public virtual RatesList RatesList { get; set; }
}
I had a similar problem with a dictionary - now I'm trying to populate a viewmodel, to return a JSON object to a GET request.
My viewmodel is:
public class HotelInventoryta
{
public int api_version { get; set; }
public string lang { get; set; }
public List<Hotel_List_ta> hotels { get; set; }
}
public class Hotel_List_ta
{
public int ta_id { get; set; }
public string partner_id { get; set; }
public string name { get; set; }
public string street { get; set; }
public string city { get; set; }
public string postal_code { get; set; }
public string state { get; set; }
public string country { get; set; }
public double latitude { get; set; }
public double longitude { get; set; }
public string desc { get; set; }
public string url { get; set; }
public string email { get; set; }
public string phone { get; set; }
public string fax { get; set; }
}
My DataBase model is:
[Table("tblHotel")]
public class Hotelta
{
[Key()]
[Column("hotel_id")]
public long hotel_id { get; set; }
public string hotel_name { get; set; }
public string hotel_add1 { get; set; }
public string hotel_towncity { get; set; }
public string hotel_pc { get; set; }
public string hotel_country { get; set; }
public string hotel_pass { get; set; }
public string hotel_email { get; set; }
public string hotel_tel { get; set; }
public string hotel_fax { get; set; }
}
My controller code to populate the viewmodel is:
private HoteltaContext dbh = new HoteltaContext();
//
// GET: /ta/hotel_inventory
[HttpGet]
public HotelInventoryta hotel_inventory(int api_version, string lang)
{
{
HotelInventoryta hotelinventory = new HotelInventoryta();
hotelinventory.api_version = api_version;
hotelinventory.lang = lang;
// Get data from database
var h = dbh.Hotelta.Where(x => x.hotel_id != 0).ToList();
// loop through each result, and add it to the hotelinventory.hotels model
foreach (var ht in h)
{
// I get the exception on the next line
hotelinventory.hotels.Add(new Hotel_List_ta
{
ta_id = 0,
partner_id = ht.hotel_id.ToString(),
name = ht.hotel_name,
street = ht.hotel_add1,
city = ht.hotel_towncity,
postal_code = ht.hotel_pc,
country = ht.hotel_country,
url = "http://www.me.com",
email = ht.hotel_email,
phone = ht.hotel_tel,
fax = ht.hotel_fax
});
}
return hotelinventory;
}
}
The error is:
Object reference not set to an instance of an object
Firstly, can you help me resolve the error - and if possible, confirm if the way I am reading from the database and populating the viewmodel, is the best way to do it?
Thank you, Mark
This is because the hotels property is never initialized. You could do this in the constructor of HotelInventoryta:
public class HotelInventoryta
{
public HotelInventoryta()
{
hotels = new List<Hotel_List_ta>();
}
// ...
}
Now you initialzed the property with an empty collection, so you can add items to it, rather than hotels being null which causes your exception.