I've been struggling with this for a bit, and can't seem to find a solution.
I have a Picker that displays a list of college terms. Binding it isn't the issue.
I also have a table of college courses. Each course needs to be attached to a specified term.
I have set the SelectedItem to a Property of the Terms table through the SelectedIndexChanged event.
On a separate page, I want to display the SelectedItem from the previous page and the list of college course attached to that term. Right now, the new page displays all the terms (with the name changed to the SelectedItem, and all the courses, regardless of which term they are attached to (through TermId).
I figured this would need to be done with a SQLite query using an inner join, but I can't seem to set the ListView ItemsSouce to that results of that query (even using ToList();), and am not even sure if thats something I should be doing.
I also thought about creating a new table, and inserting the values of the query into that table and binding it that way.
Any advice on the best way to accomplish this?
Terms table:
public class Terms
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string TermName { get; set; }
public string TermStatus { get; set; }
public DateTime TProjStart { get; set; }
public DateTime TProjEnd { get; set; }
public DateTime TActStart { get; set; }
public DateTime TActEnd { get; set; }
public string Pick { get; set; }
}
Courses Table:
public class Courses
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string CourseName { get; set; }
public string CourseStatus { get; set; }
public DateTime CourseStart { get; set; }
public DateTime CourseEnd { get; set; }
public string InstructName { get; set; }
public string InstructEmail { get; set; }
public string InstructPhone { get; set; }
public string Notes { get; set; }
public int TermId { get; set; }
}
The TermId is supposed to reference Terms.Id as a sort of foreignkey, but I can't seem to actually make it a foreignkey, so I was thinking I may need to manually set it.
Picker SelectedIndexChanged event:
public void termPicker_SelectedIndexChanged(object sender, EventArgs e)
{
using (SQLiteConnection conn = new SQLiteConnection(App.DatabaseLocation))
{
var pick = (Terms)termPicker.SelectedItem;
if (termPicker.SelectedItem != null)
{
conn.Execute($"UPDATE Terms SET Pick ='{pick.TermName}'");
}
else
{
var refresh = new Page1();
Navigation.InsertPageBefore(refresh, this);
Navigation.PopAsync();
}
Now just need to figure out a way to display only the courses attached
to the selected term
var courses = db.Table<Courses>().Where(c => c.TermId == selectedTerm).ToList();
Related
I am working ASP.NET MVC using Entity frame work code first approach. I am facing an issue ,the issue is as i have dropped two tables by using Package Manager Console.
Now i am trying to add the tables, the tables are not getting added using Package Manager Console.
Getting Error Cannot find the object "dbo.Movies" because it does not exist or you do not have permissions.
Even in Indentity.cs Model [Movies] is mentioned.
public DbSet Movies { get; set; }
Below are the Model.
public class Movie
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime ReleaseDate { get; set; }
public Genre Genres { get; set; }
public byte GenreId { get; set; }
public DateTime DateAdded { get; set; }
public int NumberOfStocks { get; set; }
}
public class Genre
{
public byte Id { get; set; }
public string Type { get; set; }
}
How to the add the new table in existing Entity frame work using Code first approach.
I'm using EF6 with ASP.Net. I'm trying to add items to the Jobs list in the following model:
EDIT:
My goal is to save the changes I make to the Timecards.Jobs list through a PUT method in such a way that I can retrieve them through a GET method.
public class Timecard
{
[Key]
public long TimecardID { get; set; }
[Required]
public DateTime StartDate { get; set; }
[Required]
public DateTime EndDate { get; set; }
[Required]
public long EmployeesID { get; set; }
[Required]
public decimal Hours { get; set; }
[Required]
public ICollection<int> Jobs { get; set; } = new List<int>();
public List<DateTime> Days { get; set; } = new List<DateTime>();
}
And I believe i'm doing so, i'm checking the states change in my PUT method:
// PUT: api/TimecardsAPI/5
[ResponseType(typeof(void))]
public IHttpActionResult PutTimecard(int id, Job job)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
try
{
Timecard card = db.Timecards.Where(x => x.TimecardID == id).First();
var state = db.Entry(card).State;
db.Timecards.Attach(card);
state = db.Entry(card).State;
card.Jobs.Add((int)job.JobID);
db.Entry(card).State = EntityState.Modified;
state = db.Entry(card).State;
var result = db.SaveChanges();
state = db.Entry(card).State;
var change = db.Timecards.Where(x => x.TimecardID == id).First().Jobs;
}
catch (DbUpdateConcurrencyException)
{
if (!TimecardExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
Before returning from the put method, i have a var change to check the results of the Jobs list once i'm done working on it. Before I leave the put method, the changes to the Jobs list are accurate. However, when I do a get, I get all the correct data EXCEPT the list. It comes back as a 0 length list. Here's my get method, which also has the jobs list in a variable. This is where the list comes back as size 0:
// GET: api/TimecardsAPI
public IQueryable<Timecard> GetTimecards()
{
var change = db.Timecards.Where(x => x.TimecardID == 6).First().Jobs;
//In this example, six is the id of the timecard in question. Only hardcoded here
//for debugging.
return db.Timecards;
}
and my dbcontext:
public class ClockedWebContext : DbContext
{
public ClockedWebContext() : base("name=ClockedWebContext")
{
}
public DbSet<Job> Jobs { get; set; }
public System.Data.Entity.DbSet<ClockedWeb.Models.PayPeriod> PayPeriods { get; set; }
public System.Data.Entity.DbSet<ClockedWeb.Models.Employee> Employees { get; set; }
public System.Data.Entity.DbSet<ClockedWeb.Models.Timecard> Timecards { get; set; }
}
There are many similar questions on SO but I have not found information yet that has helped me solve my issue. I have no idea what I'm doing wrong, but I've lost days on this and I could really use some help. thank you.
Generally storing multiples values in column is an indication of poor database design. Relational databases are designed specifically to store one value per row/column combination. In order to store more than one value, you must serialize your list into a single value for storage, then deserialize it upon retrieval or you can use many-to-one relationship then you should use an extra table with a foreign key constraint. There is no other way to do so in RDMS.
If you use serialize approach, then your model look like--
public class Timecard
{
[Key]
public long TimecardID { get; set; }
[Required]
public DateTime StartDate { get; set; }
[Required]
public DateTime EndDate { get; set; }
[Required]
public long EmployeesID { get; set; }
[Required]
public decimal Hours { get; set; }
[NotMapped]
public List<int> JobList { get; set; } = new List<int>();
[Required]
public string Jobs
{
get => string.Join(",", JobList);
set
{
if (string.IsNullOrEmpty(value)) JobList = new List<int>();
else
{
JobList = !string.IsNullOrWhiteSpace(value) && value.Contains(",")
? value.Split(',').Select(s => Convert.ToInt32(s.Trim())).ToList()
: !string.IsNullOrWhiteSpace(value) && !value.Contains(",")
? new List<int>()
: new List<int>();
}
}
}
//have to change also
public List<DateTime> Days { get; set; } = new List<DateTime>();//Follow previous technique
}
Then you can do your operation as you doing. just it's insert data as a coma separated string.
I am not getting you correctly but if you not getting the update after you changed your entity then can you please add below line
db.savechanges();
I'm trying to use the feature documented here :
https://github.com/ServiceStack/ServiceStack.OrmLite#custom-sql-customizations
This is how I'm using it:
var q = Db.From<MemberAccess>().LeftJoin<Member>();
return Db.Select<MemberResponse>(q);
Response object:
public class MemberResponse
{
public Guid Id { get; set; }
public string MemberFirstName { get; set; }
public string MemberLastName { get; set; }
public string MemberEmail { get; set; }
[Default(OrmLiteVariables.SystemUtc)]
public string AccessedOn { get; set; }
[CustomSelect("CONCAT(LEFT(Member.FirstName, 1),LEFT(Member.LastName,1))")]
public string MemberInitial { get; set; }
}
It seems like whatever I put in CustomSelect doesn't get used. Maybe, I'm not using this correctly? Also, the Default attribute doesn't work either.I tried that as it was an example from the doco.
Any idea will be appreciated.
Thanks in advance.
The [CustomSelect] only applies to the source table. Selecting the results in a custom type is used to map the returned resultset on the MemberResponse type, it doesn't have any effect on the query that gets executed.
Likewise with [Default(OrmLiteVariables.SystemUtc)] that's used to define the default value when creating the table which is only used when it creates the Column definition, so it's only useful on the source Table Type.
Both these attributes should only be added on the source MemberAccess to have any effect, which your mapped MemberResponse can access without any attributes, e.g:
public class MemberResponse
{
public Guid Id { get; set; }
public string MemberFirstName { get; set; }
public string MemberLastName { get; set; }
public string MemberEmail { get; set; }
public string AccessedOn { get; set; }
public string MemberInitial { get; set; }
}
Sql.Custom() API
The new Sql.Custom() API added in v4.5.5 that's available on MyGet will let you select a custom SQL Fragment, e.g:
var q = Db.From<MemberAccess>().LeftJoin<Member>()
.Select<MemberAccess,Member>((a,m) => new {
Id = a.Id,
MemberFirstName = m.FirstName,
MemberLastName = m.LastName,
MemberEmail = m.Email,
MemberInitial = Sql.Custom("CONCAT(LEFT(Member.FirstName,1),LEFT(Member.LastName,1))")
});
return Db.Select<MemberResponse>(q);
I’m coming from an intermediate C++ background (and to a lesser extent, C#) and wanted to try to build a project in Asp.net MVC 6 with EF 7 – not realizing how completely different it is from simple C# forms. I’ve stumbled through and researched a lot but since I’m a total noob I’m stumped at this point.
I have the following models:
public class Shift
{
public int ShiftId { get; set; }
//other properties
public virtual ICollection<ShiftActivity> ShiftActivity { get; set;}
}
public class ShiftActivity
{
public int ShiftActivityID { get; set; }
public DateTime StartTime { get; set; }
public int ShiftID { get; set; }
public int ActivityID { get; set; }
public int LocationID { get; set; }
public virtual Shift Shift { get; set; }
public virtual Activity Activity { get; set; }
public virtual Location Location { get; set; }
}
public class Activity
{
public int ActivityID { get; set; }
public string ActivityName { get; set; }
public virtual ICollection<ShiftActivity> ShiftActivity { get; set; }
}
public class Location
{
public int LocationID { get; set; }
public string LocationName { get; set; }
public string LocationAddress { get; set; }
public int locationZip { get; set; }
public virtual ICollection<ShiftActivity> ShiftActivity { get; set; }
}
I would like to create a shift and be able to input all the required fields all from one view. For instance, when I create the shift, I need to pick the type of location and activity to add to the ShiftActivity table which is then updated. Eventually I would like to be able to dynamically add additional activities (I’m assuming I’ll need javascript for that), but that’s another issue. I know I need a viewmodel to access all the tables, but I’m unclear as to how the viewmodel should be structured correctly.
Also, can the ShiftController update the ShiftActivity table directly or do I need to transfer the data somehow to the ShiftAcitivityController when the form is submitted? Either way, can someone point me to an example? Thank you… Any help is greatly appreciated.
I'm wondering what's the best way to handle default values for relationships when making models. (Specifically EF4)
For example, my Organization has a default Contact and I was wondering which one was the best approach. I got these two options (or any other anyone suggests if better)
Using Relationship:
public class Contact
{
public int Id { get; set; }
public string FirstName { get; set; }
}
public class Organization
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Contact> Contacts { get; set; }
//Use a relationship for the default contact?
public Contact DefaultContact { get; set; }
}
Using Value:
public class Contact
{
public int Id { get; set; }
public string FirstName { get; set; }
//Use value?
public boolean IsDefault { get; set; }
}
public class Organization
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Contact> Contacts { get; set; }
}
I'd go with Option 1. While 2 is definitely easier to implement, it doesn't enforce rules such as "There cannot be 2 default contacts". I end up with something like the following:
public class Organization {
// ...
public virtual ICollection<Contact> { get;set; }
[ForeignKey("DefaultContactId")]
public Contact DefaultContact { get;set; }
public int? DefaultContactId { get;set; }
}
There's a limitation of this approach - it doesn't work nested deletes (see this question for more details). Because of this, you need to disable CascadeOnDelete for the 1-to-many relationship:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Contact>().HasRequired(co => co.Organization).WithMany().WillCascadeOnDelete(false);
}
(Code done without testing, but should work)
The other problem with this is that it's not possible to add the Default Contact at the same time as you're adding the organization, as EF can't figure out the correct order of statements. You need to call .SaveChanges between each. You can still use a TransactionScope to overcome this, but it's not clean:
using (var ts = new TransactionScope())
{
Organization org = new Organization
{
// ...
Contacts = new Collection<Contact>()
}
org.Contacts = new Contact() {};
orgRepo.SaveChanges();
// Now wire up the default contact
org.DefaultContact = org.Contacts.First();
orgRepo.SaveChanges();
}