Retrieving value from combobox Winforms / Entity Framework - c#

I am trying to populate my combobox with a list of companies and then get value of selected company (its Id) into my database.
I have this class CBItem:
public class CBItem
{
public string Name { get; set; }
public int Value { get; set; }
public override string ToString()
{
return Name;
}
}
I add items to combobox using this:
using (var db = new DataContext())
{
var list_of_companies = db.Companies;
foreach (Company c in list_of_companies)
{
CBItem item = new CBItem();
item.Name = c.Name;
item.Value = c.Id;
comboBox1.Items.Add(item);
}
}
Problem is when I want to get value of selected item, I have tried something like this:
new_person.Company.Id = (comboBox1.SelectedItem).Value;
Of course it doesn't work :/ Any tips?

You are right, there is something wrong with this line:
new_person.Company.Id
I don't know what is wrong. I have model Person which has foreign key to company's id.
Maybe there si something wrong with my DB model.
My Person model:
public class Person
{
public Person()
{
}
public int PersonId { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Job { get; set; }
public int Phone { get; set; }
public int Mobile { get; set; }
public Company Company { get; set; }
}
Company model:
public class Company
{
public Company()
{
}
public int Id { get; set; }
public string Name { get; set; }
public int NIP { get; set; }
public string Address { get; set; }
public string City { get; set; }
public int Code { get; set; }
public int Phone { get; set; }
public string Notes { get; set; }
public ICollection<Person> Person { get; set; }
}
Saving code:
using (var db = new DataContext())
{
Person new_person = new Person();
new_person.Name = textBox1.Text;
new_person.Surname = textBox2.Text;
new_person.Job = textBox3.Text;
new_person.Phone = Int32.Parse(textBox4.Text);
new_person.Mobile = Int32.Parse(textBox5.Text);
new_person.Company.Id = (comboBox1.SelectedItem as CBItem).Value;
db.Person.Add(new_person);
db.SaveChanges();
MessageBox.Show("Person successfully added!");
this.Close();
}

Your code works fine if:
new_person is not null
new_person.Company is not null
combobox.SelectedItem is not null
Also you have to cast combobox.SelectedItem to CBItem like this:
new_person.Company.Id = ((CBItem)comboBox1.SelectedItem).Value;
As a site note instead of adding each item one by one you can archive the same thing by binding the ComboBox via its DataSource property to an object that implements the IList interface or an Array:
comboBox1.DataSource = list_of_companies
.Select(c => new CBItem {
Name = c.Name,
Value = c.Id
})
.ToArray();

Related

Correct way to set up a 1 to Many So I can Query Attributes on the Included table with Entity Framework 6

I currently have a 2 table set up. I can include the Associated table with ease but I would like to be able to use a condition in the Where Clause and not sure where I need to change it. The relationship is a People can have Many Address
public partial class People
{
public People()
{
Address = new HashSet<Address>();
}
public int Id { get; set; }
public int Name { get; set; }
public virtual ICollection<Address> Address { get; set; }
}
public partial class Address
{
public int id { get; set; }
public string State { get; set; }
public int PeopleId { get; set; }
public People People { get; set; }
}
I can currently do this and it includes the Associated Data, but this returns more data than I need.
using (DBContextdb = new DBContext())
{
var oooo = db.People.IncludeOptimized(x => x.Address).ToListAsync();
}
I would like to do something along these lines but I need to get my relations set up correctly. This Doesn't actually let me select the property of State on the Address class.
using (DBContext db = new DBContext())
{
var oooo = db.People.IncludeOptimized(x => x.Address).Where(x => x.Address.State == "Florida").ToListAsync();
}
You can't access the 'state' Property because 'x.Address' is a collection.
Also the State-Property is of the type int?. But you try to compare it with the string "Florida". So you should also change that.
So if you need all Addresses which have the State 'Florida' you can use something like this:
A simplified Model class:
public class Model1
{
public IQueryable<People> People { get; set; }
public IQueryable<Address> Addresses { get; set; }
public Model1()
{
People = new List<People>().AsQueryable() ;
Addresses = new List<Address>().AsQueryable();
}
}
The new Address/People classes:
public partial class People
{
public People()
{
Address = new HashSet<Address>();
}
public int Id { get; set; }
public int Name { get; set; }
public virtual ICollection<Address> Address { get; set; }
}
public partial class Address
{
public int Id { get; set; }
public string State { get; set; }
public int PeopleId { get; set; }
public People People { get; set; }
}
And then you can use the following code:
Model1 model = new Model1();
var queryResult = model.Addresses.Where(a => a.State == "Florida");
EDIT
Here is the query you are looking for:
IQueryable<People> queryResult = model.Addresses.Where(a => a.State == "Florida").Select(a => a.People);

Entity Framework save collection

I have Entity Framework Code First models. When I try save collection of Accounts in one insert i get error message.
public class User
{
[Key]
public int Usr_Id { get; set; }
[Required]
[MaxLength(35)]
public string Name { get; set; }
[Required]
[MaxLength(35)]
public string Surname { get; set; }
[Required]
[MaxLength(35)]
public string Location { get; set; }
//NAVIGATION
public User()
{
UserDevices = new List<UserDevice>();
}
public virtual ICollection<UserDevice> UserDevices { get; set; }
}
public class UserDevice
{
[Key]
public int UsrDev_Id { get; set; }
[Required]
[MaxLength(50)]
public string PurposeOfUse { get; set; }
// NAVIGATION
public UserDevice()
{
Accounts = new List<Account>();
}
//User can have many UserDevice
public int Usr_Id { get; set; }
public virtual User User { get; set; }
//UserDevice can have many Acoount
public virtual ICollection<Account> Accounts { get; set; }
//One to one
public virtual SoftwareInformation SoftwareInformation { get; set; }
public virtual HardwareInformation HardwareInformation { get; set; }
}
public class Account
{
[Key]
public int Acc_Id { get; set; }
public string Name { get; set; }
//NAVIGATION
//UserDevice can have many Account
public int UsrDev_Id { get; set; }
public virtual UserDevice UserDevice { get; set; }
}
Insert of new UserDevice
List<Account> accountsList = new List<Account>();
foreach (var item in model.DeviceInformations.OS.Accounts)
{
accountsList.Add(new Account { Name = item.Name });
}
_unitOfWork.UserDevices.Add(new UserDevice
{
Usr_Id = model.Usr_Id,
PurposeOfUse = model.PurposeOfUse,
HardwareInformation = new HardwareInformation
{
MB_Manufacturer = model.DeviceInformations.Motherboard.Manufacturer,
MB_Model = model.DeviceInformations.Motherboard.Model,
MB_Name = model.DeviceInformations.Motherboard.Name,
MB_UUID = model.DeviceInformations.Motherboard.UUID,
CPU_Manufacturer = model.DeviceInformations.Processor.Manufacturer,
CPU_MaxClockSpeed = model.DeviceInformations.Processor.MaxClockSpeed,
CPU_Name = model.DeviceInformations.Processor.Name,
},
SoftwareInformation = new SoftwareInformation
{
OS_Edition = model.DeviceInformations.OS.Edition,
OS_HostName = model.DeviceInformations.OS.HostName,
OS_Language = model.DeviceInformations.OS.Language,
OS_Platform = model.DeviceInformations.OS.Platform,
OS_ProductKey = model.DeviceInformations.OS.ProductKey,
OS_ServicePackVersion = model.DeviceInformations.OS.ServicePackVersion,
OS_Version = model.DeviceInformations.OS.Version
},
Accounts = accountsList
});
_unitOfWork.Commit();
Error message
{"Cannot insert the value NULL into column 'Acc_Id', table 'LICENSE_WATCHER_TEST.dbo.Accounts'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated."}
It happends when I try save Accout collection. Is there a way how to save Accouts collection in one Insert?
Acc_id is null on insert. I would expect that ID to be auto generated in cases like this. Is it possible that you have the Acc_id column on the Account Table set up as PK, but not an Identity column in the database?
That might cause the behavior that you are experiencing.
Well, you have Acc_Id defined as Primay key and it seems you are trying to insert a null value to table.
Here you create account list, but you only fill in Name
foreach (var item in model.DeviceInformations.OS.Accounts)
{
accountsList.Add(new Account { Name = item.Name });
}
And then you don't do any changes in accountsList
Before commit you do Accounts = accountsList which doesn't have Id filled in and you try to commit.
Try something like this:
foreach (var item in model.DeviceInformations.OS.Accounts)
{
accountsList.Add(new Account { Acc_Id = !!someIdHere!!, Name = item.Name });
}

Using LINQ To Select Records Based on Child Collections item

i have instructor class.
public partial class Instructor
{
public Instructor()
{
this.Courses = new HashSet<Course>();
this.Courses1 = new HashSet<Course>();
}
public int ID { get; set; }
public string FName { get; set; }
public string LName { get; set; }
public int UserID { get; set; }
public virtual ICollection<Course> Courses { get; set; }
public virtual User User { get; set; }
public virtual ICollection<Course> Courses1 { get; set; }
}
i want to search for instructor by name and course that he teaches
i used predicate to build my condition
but i need to access courses 1 collection inside instructor to get instructors whom teach this course but i can't
var Predict = PredicateBuilder.True<Instructor>();
if (chkNameSearch.Checked)
{
Predict = Predict.And(ins => ins.FName == txtNameSearch.Text);
}
if (chkCourseSearch.Checked)
{
int CourseID=int.Parse(cmbCourseSearch.SelectedValue.ToString());
Predict = Predict.And(ins => ins.Courses1.ID == CourseID); //Error
}
Courses1 doens't have any ID property. Try doing this:
Predict = Predict.And(ins => ins.Courses1.Any(c => c.ID == CourseID));

Populate a datagridview

I have a List of "Person" object:
public class Person
{
public Int32 Id { get; set; }
public String Name { get; set; }
public Document oDocument { get; set; }
}
And also there is Document class.
public class Document
{
public String Type { get; set; }
public String Code { get; set; }
}
I need to populate a DataGridView with that list showing some just two columns:Name(Person) and DocumentCode (Document)
I used this code, but I dont get what I want.
dgvPersona.DataSource = list;
You need to select an anonymous type object (to project required fields) and then bind that to your gridview like:
var list = (from p in persons
select new
{
Name = p.Name,
DocumentCode = p.Document.Code
}).ToList();
dgvPersona.DataSource = list;
You may select the Id as well and keep it in a hidden column in your gridview , so that later you can use it for record updating etc.
try this:
public class Person
{
public Int32 Id { get; set; }
public String Name { get; set; }
public Document oDocument { get; set; }
}
public class Document
{
public String Type { get; set; }
public String Code { get; set; }
}
List<Person> list = new List<Person>();
dgvPersona.DataSource= list.Select(data => new { data.Name, data.oDocument.Code }).ToList();

What would be the better way of getting linked models values from db

First of all, I'm very new to the ASP.NET MVC C# and EF. I'm in a process of creating a website that should hopefully help me learn these three wonderful technologies. with that said, I have the following models in my project.
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string FirstName { get; set; }
public string Lastname { get; set; }
public string EmailAddress { get; set; }
//public string PhoneNumber { get; set; }
public bool? ChangePassword { get; set; }
public bool? Deletable { get; set; }
//Add more Properties for more fields
public virtual ICollection<CompanyInformation> ParentCompanies { get; set; }
public virtual StaffProfile sProfile { get; set; }
}
And
public class StaffProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int StaffProfileId { get; set; }
public string Alias { get; set; }
public StaffGrouping Group { get; set; }
public ICollection<PhoneNumber> PhoneNumbers { get; set; }
public bool isPhoneNumberDisplayed { get; set; }
public bool TextNotificationsAllowed { get; set; }
public bool EmailNotificationsAllowed { get; set; }
public bool PhoneNotificationsAllowed { get; set; }
}
Staff Grouping
public class StaffGrouping
{
public int id { get; set; }
public string GroupName { get; set; }
}
and just for completeness, the phone numbers model
public class PhoneNumber
{
public int id { get; set; }
public string Number { get; set; }
public string Extension { get; set; }
public PhoneType Type { get; set; }
public bool isPrimary { get; set; }
public bool isInActive { get; set; }
}
public enum PhoneType {
Home,
Mobile,
Work,
Other
}
I'm trying to get all the staffs from the db (including the phone numbers, userprofile and group they are linked to) and adding it to a viewmodel for better integration with my view. currently I'm doing it as such:
public ActionResult ManageStaff()
{
using (var repo = new CompanyInformationRepository(new UniteOfWorkCompanies()))
{
var company = repo.FindCompany(User.Identity.Name);
var Users = repo.CompanyStafflookup(company);
var model = new List<StaffManagementViewModel>();
foreach (var user in Users)
{
var group = repo.StaffGroupLookup(user.sProfile);
//var phoneNumber = user.sProfile.PhoneNumbers.Where(p => p.isPrimary == true).FirstOrDefault();
model.Add(new StaffManagementViewModel
{
FirstName = user.FirstName,
LastName = user.Lastname,
EmailAddress = user.EmailAddress,
PhoneNumber = "(915) 433 - 1739", //phoneNumber.Number,
Group = group.GroupName,
UserID = user.UserId
});
}
return View(model);
}
And my repository:
public IQueryable<HoursOfOperation> CompanyHoursLookup(string userName)
{
var company = FindCompany(userName).id;
//var model = _db.HoursOfOperations.Where(e => e.Company.id == company);
var model = from h in _db.HoursOfOperations
where h.Company.id == company
orderby h.Day ascending, h.From ascending
select h;
return model;
}
public IQueryable<UserProfile> CompanyStafflookup(CompanyInformation company)
{
var model = from s in _db.UserProfiles.Include("sProfile")
where s.ParentCompanies.Any(e => e.companyName == company.companyName)
orderby s.FirstName ascending
select s;
return model;
}
public StaffGrouping StaffGroupLookup(StaffProfile Staff)
{
var Staffwithgroup = _db.StaffProfiles.Where(e => e.StaffProfileId == Staff.StaffProfileId).Include("Group").FirstOrDefault();
return Staffwithgroup.Group;
}
I'm guessing there should be a better more efficient way of doing this as I'm counting at least three trips to the database. I tried to use the .include but on the userprofile but since I don't have a navigation Property to point at the group, its giving me an error. the code I'm talking about is the following:
var model = from s in _db.UserProfiles.Include("sProfile").Include("PhoneNumbers").Include("Group")
where s.ParentCompanies.Any(e => e.companyName == company.companyName)
orderby s.FirstName ascending
select s;
Is there a way to achieve this in one call that basically would return a list of UserProfiles that includes the StaffProfile that includes the PhoneNumbers and finally the Group?
You can simply prefix the include with the full path, i.e. use:
Include("sProfile.Group")
This will include both StaffProfile and it's Group.

Categories