Cannot insert the value NULL into column from unrelated entity - asp.net-mvc

I'm getting a "Cannot insert null into column" error from an unrelated table when trying to add a new record for the "original" table.
I have the following two (relevant) entities:
public class Complex
{
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
public Guid OwnerId { get; set; }
[ForeignKey("OwnerId")]
public Owner Owner { get; set; }
public Guid AddressId { get; set; }
[ForeignKey("AddressId")]
public virtual Address Address { get; set; }
public virtual ICollection<Unit> Units { get; set; }
public virtual ICollection<StaffMember> StaffMembers { get; set; }
public Complex()
{
this.Id = System.Guid.NewGuid();
this.Units = new HashSet<Unit>();
this.StaffMembers = new HashSet<StaffMember>();
}
public void AddUnit(Unit unit)
{
Units.Add(unit);
}
public void AddStaff(StaffMember staffMember)
{
StaffMembers.Add(staffMember);
}
}
and
public class Owner
{
[Key]
public Guid Id { get; set; }
public string Name { get; set; }
public Guid ContactInfoId { get; set; }
[ForeignKey("ContactInfoId")]
public ContactInfo ContactInfo { get; set; }
public ICollection<StaffMember> Employees { get; set; }
public ICollection<Complex> Complexes { get; set; }
public Owner()
{
this.Id = System.Guid.NewGuid();
this.Employees = new HashSet<StaffMember>();
this.Complexes = new HashSet<Complex>();
}
public void AddEmployee(StaffMember employee)
{
Employees.Add(employee);
}
public void AddComplex(Complex complex)
{
Complexes.Add(complex);
}
}
I'm trying to add a new owner in the following code:
if (ModelState.IsValid)
{
Owner newOwner = new Owner();
ContactInfo newContactInfo = new ContactInfo();
Address newAddress = new Address();
newAddress.Address1 = viewModel.ContactInfo.Address.Address1;
newAddress.Address2 = viewModel.ContactInfo.Address.Address2;
newAddress.City = viewModel.ContactInfo.Address.City;
newAddress.State = viewModel.ContactInfo.Address.State;
newAddress.Zip = viewModel.ContactInfo.Address.Zip;
newContactInfo.Address = newAddress;
newContactInfo.Email = viewModel.ContactInfo.Email;
newContactInfo.Phone1 = viewModel.ContactInfo.Phone1;
newContactInfo.Phone2 = viewModel.ContactInfo.Phone2;
newOwner.Name = viewModel.Name;
newOwner.ContactInfo = newContactInfo;
using (REMSDAL dal = new REMSDAL())
{
dal.Owners.Add(newOwner);
var result = await dal.SaveChangesAsync();
if (result > 0)
{
viewModel.ActionStatusMessageViewModel.StatusMessage = "Owner " + viewModel.Name + " added.";
viewModel.Name = "";
return View(viewModel);
}
}
}
...but getting this error:
Exception Details: System.Data.SqlClient.SqlException: Cannot insert the value NULL into column 'OwnerId', table 'REMS.dbo.Complexes'; column does not allow nulls. UPDATE fails.
The statement has been terminated.
How can I be getting an error regarding Complexes when I'm trying to add an Owner?

Related

MVC How do I create a new object with default value

I have a view that has add/edit, edit is working fine but for add I would like to set default values for type. Is there a way to do this in the view the cshtml file?
add view
#Html.Partial("RegimenReferences", new (ReferencesModel {Type = "defaultType}") )
edit view
#Html.Partial("RegimenReferences", (ReferencesModel)Model)
Model
public class ReferencesModel
{
public ReferencesModel()
{
}
public ReferencesModel(Reference reference)
{
this.Id = reference.Id;
this.Link = reference.Link;
this.Text = reference.Text;
this.Type = reference.Type;
this.Regimens = reference.Regimens;
this.GuidelineId = reference.GuidelineId;
this.SortOrder = reference.SortOrder;
}
public long Id { get; set; }
public string Link { get; set; }
public string Text { get; set; }
public string Type { get; set; }
public int Regimens { get; set; }
public Guid? GuidelineId { get; set; }
public int SortOrder { get; set; }
}
}
Are you wanting to set those types specifically in cshtml?
Could you create a new constructor for your model that takes in any fields you want to set with a default?
public class ReferencesModel
{
public ReferencesModel(string type = null)
{
Type = type;
}
public ReferencesModel(Reference reference)
{
this.Id = reference.Id;
this.Link = reference.Link;
this.Text = reference.Text;
this.Type = reference.Type;
this.Regimens = reference.Regimens;
this.GuidelineId = reference.GuidelineId;
this.SortOrder = reference.SortOrder;
}
public long Id { get; set; }
public string Link { get; set; }
public string Text { get; set; }
public string Type { get; set; }
public int Regimens { get; set; }
public Guid? GuidelineId { get; set; }
public int SortOrder { get; set; }
}
or just set a default value in the constructor/in variable declaration
public ReferencesModel()
{
Type = "default type";
}
public string Type = "default type";

how to access elements of a list in controller

Entities
public class Employee
{
public long BusinessUnitID{ get; set; }
public long EmployeeID { get; set; }
public long InfoTypeID { get; set; }
public string EmployeeName { get; set; }
public List<ContactData> ContactDetails{ get; set; }
}
public class ContactData
{
public string ContactTypeName { get; set; }
public string ContactValue { get; set; }
}
Model
Public class EmployeeDetails
{
public long BusinessUnitID { get; set; }
public List<EmployeeData> EmployeeInfo { get; set;}
public List<ContactInfo> Contacts { get; set; }
}
public class EmployeeData
{
public long EmployeeID { get; set;}
public string EmployeeName { get; set;}
}
Public class ContactInfo
{
public string ContactName { get; set; }
public long ContactValue { get; set; }
}
Controller
public ActionResult Update(long BusinessUnitID=2)
{
if (Session[Constants.Session_IsAdmin] != null && Convert.ToBoolean(Session[Constants.Session_IsAdmin]))
{
EmployeeDetails employeeDetails = new EmployeeDetails();
List<Employee> employee = GetEmployeeById(Convert.ToInt64(BusinessUnitID));
List<EmployeeData> lstEmployeeData = new List<EmployeeData>();
List<ContactInfo> lstContactInfo = new List<OptionDetails>();
var ID = employee.Select(x => x.BusinessUnitID).ToList();
foreach(var item in employee.Where(x => x.BusinessUnitID == BusinessUnitID))
{
EmployeeData employeeData = new EmployeeData();
employeeData.EmployeeID = item.EmployeeID;
employeeData.EmployeeName = item.EmployeeName;
foreach (var local in employee.Where(q => q.EmployeeID == employeeData.EmployeeID))
{
//ContactInfo contactInfo = new ContactInfo();
//contactInfo.ContactName = local.ContactDetails.Select(p => p.ContactName).ToString();
//contactInfo.ContactValue = local.ContactDetails.Select(s => s.ContactValue).ToString();
}
lstEmployeeData.Add(employeeData);
}
return View(EmployeeDetails);
}
else
{
return RedirectToAction("Login");
}
}
Here I'm getting a list Employee in which i have below properties and a list ContactDetails which is a list containing atleast 3 elements for its properties. For eg 3 types of ContactTypeName and ContactValue as Home: 000000000, work: 9999999, mobile: 8888888. For a businessUnitid i got all employeeid for a perticular EmployeeID i want contact details but i'm unable to get or 3 contactvalue and contactname. In list Employee there is list ContactDetails in which there would be 3 or 5 contact numbers. I don't know how must i assign it to a list.
As employee can have multiple contact details, you need to add contact detail list property to EmployeeData class
Model classes :
Public class EmployeeDetails
{
public EmployeeDetails()
{
EmployeeInfo = new List<EmployeeData>();
}
public long BusinessUnitID { get; set; }
public List<EmployeeData> EmployeeInfo { get; set;}
}
public class EmployeeData
{
public EmployeeData()
{
Contacts = new List<ContactInfo>();
}
public long EmployeeID { get; set;}
public string EmployeeName { get; set;}
public List<ContactInfo> Contacts { get; set; }
}
Public class ContactInfo
{
public string ContactName { get; set; }
public long ContactValue { get; set; }
}
Then it's easy to pass the data of employees with multiple contacts
public ActionResult Update(long BusinessUnitID=2)
{
if (Session[Constants.Session_IsAdmin] != null && Convert.ToBoolean(Session[Constants.Session_IsAdmin]))
{
List<Employee> employees = GetEmployeeById(Convert.ToInt64(BusinessUnitID));
List<EmployeeData> lstEmployeeData = new List<EmployeeData>();
foreach(var item in employee.Where(x => x.BusinessUnitID == BusinessUnitID))
{
EmployeeData employeeData = new EmployeeData();
employeeData.EmployeeID = item.EmployeeID;
employeeData.EmployeeName = item.EmployeeName;
foreach (var contact in employee.ContactDetails)
{
ContactInfo contactInfo = new ContactInfo();
contactInfo.ContactName = contact.ContactName;
contactInfo.ContactValue = contact.ContactValue;
employeeData.Contacts.Add(contactInfo);
}
lstEmployeeData.Add(employeeData);
}
EmployeeDetails empDetails = new EmployeeDetails();
empDetails.EmployeeInfo = lstEmployeeData;
return View(empDetails);
}
else
{
return RedirectToAction("Login");
}
}

How to retrieve list of data in model

I have data in model and I used to store that data in session as below in controller
if (providerListingModel.ServiceDetails != null && providerListingModel.ServiceDetails.Count > 0)
Session["ServiceDetails"] = providerListingModel.ServiceDetails;
else
Session["ServiceDetails"] = null;
and for retrieving I had used the logic as
if (Session["ServiceDetails"] != null)
{
if (providerListingModel.ServiceDetails == null)
{
List<ServiceDetail> sam = (List<ServiceDetail>)Session["ServiceDetails"];
foreach (var items in sam)
{
var sd = new ServiceDetail();
sd.Id = items.Id;
sd.CategoryServiceId = items.CategoryServiceId;
sd.ServiceType = items.ServiceType;
sd.ServicePrice = items.ServicePrice;
sd.IsSelected = items.IsSelected;
sd.ProviderListingId = providerListingModel.ProviderListingId;
providerListingModel.ServiceDetails.Add(sd);
}
}
Session["ServiceDetails"] = null;
}
The session contains data but on providerListingModel.ServiceDetails.Add(sd); it throw null exception.
ServiceDetails is a class and it contains list of items
namespace xyz.DAL
{
using System;
using System.Collections.Generic;
public partial class ServiceDetail
{
public int Id { get; set; }
public int ProviderListingId { get; set; }
public Nullable<int> CategoryServiceId { get; set; }
public string ServiceType { get; set; }
public Nullable<int> ServicePrice { get; set; }
public string CustomeService { get; set; }
public Nullable<bool> IsSelected { get; set; }
public virtual CategoryService CategoryService { get; set; }
public virtual ProviderListing ProviderListing { get; set; }
}
}
am I missing some code?
As I am new I don't know what I am doing wrong
You are inserting the item to null value, so it throws an error. Create new instance of the list and add an item to collection.
if(providerListingModel.ServiceDetails ==null)
providerListingModel.ServiceDetails = new List<ServiceDetail>();

Code First Many to Many : how to add a collection to an object

I have a Many to Many relationship between User and Role. They are set up as follows :
public partial class User
{
//public User()
//{
// //this.DateCreated = DateTime.Now; //set default value
// Roles = new HashSet<Role>();
//}
public ICollection<Role> Roles { get; set; } //many to many relationship
public int UserId { get; set; }
public string FirstName { get; set; }
public string Surname { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string City { get; set; }
//foreign key
public int CountryId { get; set; }
//navigation properties
public virtual Country Country { get; set; }
//foreign key
public int LanguageId { get; set; }
//navigation properties
public virtual Language Language { get; set; }
public string EmailAddress { get; set; }
public long? FacebookId { get; set; }
public DateTime DateCreated { get; set; }
}
public partial class Role
{
//public Role()
//{
// Users = new HashSet<User>();
//}
public ICollection<User> Users { get; set; } //many to many relationship
public int RoleId { get; set; }
public string RoleName { get; set; }
}
//many to many relationship
modelBuilder.Entity<User>().
HasMany(c => c.Roles).
WithMany(p => p.Users).
Map(
m =>
{
m.MapLeftKey("UserId");
m.MapRightKey("RoleId");
m.ToTable("UserRoles", schemaName: "Main");
});
In my code where I add a new user, I want to be able to add Roles to that user. But whenever I do this, new Roles are also added to the Roles table. What is the correct way to do this?
[HttpPost]
public ActionResult UserAdd(UserDTO user)
{
if (ModelState.IsValid)
{
//do mapping manually here
Country country = _repository.GetCountryByCountryId(user.CountryId);
Language language = _repository.GetLanguageByLanguageId(user.LanguageId);
User entity = new User();
entity.FirstName = user.FirstName;
entity.Surname = user.Surname;
entity.Username = user.Username;
entity.Password = user.Password;
entity.City = user.City;
entity.CountryId = country.CountryId;
entity.LanguageId = language.LanguageId;
entity.Country = country;
entity.Language = language;
entity.EmailAddress = user.EmailAddress;
entity.FacebookId = null;
entity.DateCreated = DateTime.Now;
entity.Roles = new List<Role>();
foreach (int i in user.Roles)
{
Role role = _repository.GetRoleByRoleId(i);
entity.Roles.Add(new Role { RoleId = i, RoleName = role.RoleName });
}
int newUserId = _repository.AddUser(entity);
return View();
} }
entity.Roles.Add(new Role { RoleId = i, RoleName = role.RoleName });
Here is the problem, because you create new instance, it means absolutely new role. You have to work with role from your context:
foreach (int i in user.Roles)
{
Role role = _repository.GetRoleByRoleId(i);
entity.Roles.Add(role); // don't create new instance here!
}

The model item passed into the dictionary is of type 'ViewModels.SiteModel',

I'm newbie to MVC architecture.When I'm trying to update, its showing error ,Its totally strange but the data is updating.
The model item passed into the dictionary is of type 'CMS.Domain.Models.Site', but this dictionary requires a model item of type 'CMS.Web.ViewModels.SiteModel'.'.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: The model item passed into the dictionary is of type 'CMS.Web.ViewModels.SiteModel', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable`1[CMS.Web.ViewModels.SiteModel]'.
My code looks like:
ViewModels:
namespace CMS.Web.ViewModels
{
public class SiteModel
{
public SiteModel()
{
SiteStatus = new List<SelectListItem>();
}
[Key]
public int ID { get; set; }
[Required(ErrorMessage = "Site Name is required")]
[Display(Name = "Site Name")]
public string Title { get; set; }
[Display(Name = "Require Login")]
public bool RequiresLogin { get; set; }
[Display(Name = "Force HTTPS")]
public bool ForceHTTPS { get; set; }
[Display(Name = "Enable Approval")]
public bool Approval { get; set; }
[AllowHtml]
public IList<SelectListItem> SiteStatus { get; set; }
public bool Deleted { get; set; }
public string CreatedBy { get; set; }
public DateTime CreatedOn
{
get { return _createdOn; }
set { _createdOn = value; }
}
private DateTime _createdOn = DateTime.Now;
public string LastUpdatedBy { get; set; }
public DateTime LastUpdatedOn
{
get { return _lastUpdatedOn; }
set { _lastUpdatedOn = value; }
}
private DateTime _lastUpdatedOn = DateTime.Now;
[Display(Name = "Site State")]
public string SiteState { get; set; }
}
}
Model:
namespace CMS.Domain.Models
{
public partial class Site : Model
{
public string Title { get; set; }
public bool Approval { get; set; }
public bool RequiresLogin { get; set; }
public bool ForceHTTPS { get; set; }
public virtual string SiteStatus { get; set; }
public bool Deleted { get; set; }
}
}
Controller:
public ActionResult Index()
{
var _sites = _siterepository.FindAll();
return View(_sites);
}
public ActionResult Add()
{
var model = new SiteModel();
var _SiteStatus = _siterepository.GetSiteStatus();
foreach (var _sitestatus in _SiteStatus)
{
model.SiteStatus.Add(new SelectListItem()
{
Text = _sitestatus.StatusName,
Value = _sitestatus.StatusName.ToString()
});
}
return View(model);
}
[HttpPost]
public ActionResult Add(SiteModel _sitemodel)
{
var model = _sitemodel.ToEntity();
_siterepository.Add(model);
return View(model);
}
public ActionResult Edit(int id)
{
var model = new SiteModel();
var Site = _siterepository.Find(id);
model = Site.ToModel();
var _SiteStatus = _siterepository.GetSiteStatus();
foreach (var _sitestatus in _SiteStatus)
{
model.SiteStatus.Add(new SelectListItem()
{
Text = _sitestatus.StatusName,
Value = _sitestatus.StatusName.ToString(),
Selected = _sitestatus.StatusName == Site.SiteStatus
});
}
return View(model);
}
[HttpPost]
public ActionResult Edit(SiteModel _sitemodel)
{
var model = _sitemodel.ToEntity();
_siterepository.Update(model);
return View(model);
}
I'm struggling to resolve this , please help.
Check your View's model declaration. It is expecting an enumerable list (IEnumerable<CMS.Web.ViewModels.SiteModel>), but you are passing it a single instance of CMS.Web.ViewModels.SiteModel

Resources