Azure Mobile Apps - POST to table with foreign key "Bad Request" 400 error - entity-framework

I'm hoping this is a simple question. I've created an Azure Mobile Apps project based upon the sample ToDo project, adding my own tables/data objects. The problem I'm having is adding/POSTing records to a table that has a foreign key relationship to another. The following is my Employee table data object:
public class Employee : EntityData
{
public string Name { get; set; }
public string EmailAddress { get; set; }
public bool IsActive { get; set; }
public string EmployeeTypeId { get; set; }
public virtual EmployeeType EmployeeType { get; set; }
}
...and this is my EmployeeType data object:
public class EmployeeType : EntityData
{
public string EmpType { get; set; }
public bool IsActive { get; set; }
}
The virtual EmployeeType property in the Employee class was necessary, I believe, to create the relationship with the EmployeeType table when using EF Code First to create the tables in the database. (At least, that's what I understand, and it worked) I am able to insert records from my Xamarin client app into the EmployeeType table using the InsertAsync method, but I receive a "Bad Request" 400 error when trying to insert into the Employee table.
I've looked around quite a bit for solutions, but everything refers to Azure Mobile Services and not Apps. If need be, I can update this question with my client side model classes (I'm on my PC now and don't have access to the Xamarin Studio project on my Mac). For reference, these classes are pretty much the same as the data objects - just each property is decorated with the JsonProperty attribute, except the virtual property outlined in the service. And for completeness, I did try adding that property to the client object and it still threw the "Bad Request" 400 error.
Thanks for any direction you can offer me.

Most likely, the problem is happening when trying to map the foreign key. Are you specifying all of the fields for employee type? I recommend that you do the following:
Use Fiddler or attach a delegating handler to your client to see what the outgoing request looks like. Update your comment with the JSON body. See https://github.com/Azure/azure-mobile-apps/wiki/Help,-my-app-isn't-working!#log-outgoing-requests-in-managed-client-xamarin-windows.
Attach a debugger to your server project. You can do this while running locally or after your solution is deployed to Azure, but you'll have better performance if you run locally. See https://github.com/Azure/azure-mobile-apps/wiki/Help,-my-app-isn't-working!#remote-debugging-net-server-sdk.
I suspect that the problem is that EmployeeType ends up being null in your deserialized object, and then Entity Framework rejects the DB insert.

Could you get more information from the bad request? Try adding this to the table controller
protected override void Initialize(HttpControllerContext controllerContext)
{
controllerContext.Configuration.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
}

Related

EF Query pulls null when dbase shows populated field

I've got an issue with EF Core in which I loop through a list of objects and create related elements in another list. As I process the first object everything is great, it is added to the list properly and looks great when we pull the information from the database.
At the start of the code for processing each object, I grab more detailed information from the database about that object (it's related objects and such). When the query executes for the second object information in another object changes. It changes a foreign key to be null for the first object instead of the proper value. If I look in the database as that occurs, the foreign key is set properly. This change in the foreign key shown in the query causes it to show as dirty in the context.
Therefore, when we finish processing the second object and make an update to the database, the system commits the (now) null foreign key to the database. This causes all sorts of issues, as you would expect.
partial object definition below
public partial class CommandType
{
public int? FkATSId { get; set; }
public virtual ATST FkATS { get; set; }
}
public partial class ATST
{
public virtual ICollection<FAT> FAT{ get; set; }
}
public partial class FAT
{
public int? FkDTRTId{ get; set; }
public virtual DTRT FkDTRT { get; set; }
}
public partial class DTRT
{
public int? FkFDTid{ get; set; }
public virtual FDT FkFDT{ get; set; }
}
public partial class FDT
{
...
}
The value that gets comes back as a change to null is FkFDTid in the DTRT.
if we are processing 5 of the items, 4 will end up with a null id and the last one will have the proper foreign key. If we processed 10, 9 would have the bad id and the last one would be good.
If I go through the code in the debugger and keep an eye on the context directly, the value does not come back from the query as null and so things work fine. But, only if I keep the context open in the locals tab of VS.
Does anyone have any ideas?
It turns out the issue was a discrepancy between the database and the entity framework context. The database for one of the items had the foreign key as not unique, but the context, for some reason, had it as unique.
We were able to store values into the database but if we queried the database and brought more than one record that had the same foreign key value, EF would think to itself: This can't be, that foreign key must be unique. I'll set the first one I grabbed to be null. Voila, they're not unique. Oh, because I changed that foreign key, the record is now dirty and will be committed to the database when we do a save changes.
The takeaway from this: if you see values that are different from what is stored in the database after you query the database, check foreign key and uniqueness constraints.

Entity Framework (C# ASP.NET) - Association Entity without Tracking in Non-Dependent Entity

I have two Model classes to be created using Entity Framework: Skill and Activity. The following are the definitions of each:
Skill.cs
public class Skill
{
public int Id { get; set; }
public String Name { get; set; }
}
Activity.cs
public class Activity
{
public int Id { get; set; }
public String Name { get; set; }
public virtual List<Skill> RequiredSkills { get; set; }
}
Ideally, in the database, I'd want the Activity to be linked via foreign key to a association entity (e.g. SkillActivityAssoc) and the Skill not to have to do anything with it. I don't need to track which activities need a certain skill. I just need to track what skills are needed for each activity thus explaining why I don't have a List in the Skill class. I hope that made sense.
My question is: Is this the right way to go about doing this? When I update the RequiredSkills property of Activity via:
activity.RequiredSkills = someInstanceOfRequiredSkillsList;
dbcontext.Entry(activity).State = EntityState.modified;
dbcontext.SaveChanges();
.., it doesn't work. I'm already speculating that it's because I'm not able to update the association entity. Moreover, my current implementation has a virtual List<Activity> property in the Skill class which I want to get rid of. How do I go about changing my model design and how do I update RequiredSkills accordingly?
Thank you in advance!
virtual is for lazy loading and track changes in EF. You can read more about it here: Understanding code first virtual properties. You should also read MSDN documentation about loading entities in EF: https://msdn.microsoft.com/en-us/library/jj574232(v=vs.113).aspx
Since you want to have more than one Skills in each Activity and each Skills can be in more than one Activity as well, you have a many-to-many relantionship. Please read this example: How to create a many-to-many mapping in Entity Framework? and this http://www.entityframeworktutorial.net/code-first/configure-many-to-many-relationship-in-code-first.aspx

Filter Context data by user input

I am using MVC with Entity framework.
I have a Client requirement that client want to set default period for all the context table. When he set some date range into the user setting page it saves the detail to the sql table. When the app runs application all the data from table will come for that particular period.
I want to apply this filter in my context file.
Here is my context file and suppose i got the date here.
public class MyContext : DbContext
{
public DbSet<Contact> Contacts { get; set; }
public DbSet<Contact_phone> Contact_phones{ get; set; }
}
How i achieve this.
Thanks

Fixing Model/Column mapping in Code First/EF6

First of all, I shot myself in the foot. I'm building a test application (this is work related, not school btw.) I have a model with a foreign key property
Home_TeamId
That mapped to a column called
Home_TeamId in my database. Everything was happy until I refactored everything to use ID instead of Id. I didn't notice the Migration added a column called Home_TeamID1 and is storing the data there instead of Home_TeamId (where I want it.)
So what I would like to do is:
Drop the column Home_TeamID1 (No problem, I can do that.)
Rename Home_TeamId to Home_TeamID. (No problem, I can do that.)
Tell EF to write the data to the original column.
I've read how to use database mappings in the DbContext, but that isn't what I'm trying to do either (i.e., this is a one-time thing, not something I need to do every time the app runs.) (BTW, there is no .edmx file either.)
So that's the question -- how do I tell EF to write the Home_TeamID field in the domain model to the Home_TeamID column in the table?
I should add that I've done another migration since then so it's not (necessarily) so easy as to just target back one revision.
Edit 1:
EF was writing the same Team ID to both the Home_TeamID and Home_TeamID1 columns, although it had made the ..ID1 file the foreign key.
I've looked everywhere on my project for the text "ID1" (both as text and as binary Unicode) and the only places it shows up are in the *_migration.cs files.
In the meantime, I've tried Steps 1 and 2 above. And now (as expected) I get:
InnerException: System.Data.SqlClient.SqlException HResult=-2146232060
Message=Invalid column name 'Home_TeamID1'.
Invalid column name 'Visitors_TeamID1'.
Edit 2:
I tried this:
Create a brand new (blank database)
Excluded all the .cs files in the Migrations from the project
add-migration InitialRecreate
Looked in the resulting .cs file and removed any reference to ID1. (In fact, there were two...where did they come from??)
Looked in the project and found 0 references to ID1.
Update-database
Ran the project
Invalid column name 'Home_TeamID1'.
So obviously the problem isn't the database itself.
It was a case of the software outsmarting the human. In my "higher-level" GameSummary class, I had:
public int GameSummaryID { get; set; }
public int Home_TeamID { get; set; }
public virtual Team Home { get; set; }
public int Visitors_TeamID { get; set; }
public virtual Team Visitors { get; set; }
And in the Team class I had:
public int TeamID { get; set; }
So EF was creating two columns, one for Home_TeamID (the field Home_TeamID in the GameSummary class) and one for Home_TeamID (the foreign key for the navigation property that pointed to the Team object). The solution:
public int GameSummaryID { get; set; }
public int HomeTeamID { get; set; }
public virtual Team Home { get; set; }
public int VisitorsTeamID { get; set; }
public virtual Team Visitors { get; set; }

Using EntityFramework.HierarchyId in CodeFirst approach, The Type hierarchyid is not qualified with a namespace or alias

I'm starting new project and I'd like to use HierarchyID in my DB model and CodeFirst approach. So I added EntityFramework.HierarchyId using nuget.
But when I run Update-Database, I receive this exception:
Schema specified is not valid. Errors:
(0,0) : error 0040: The Type hierarchyid is not qualified with a namespace or alias. Only primitive types can be used without qualification.
This is how my table looks like:
public class Activity
{
[Key]
public int ActivityId { get; set; }
public HierarchyId ActivityPath { get; set; }
public string Name { get; set; }
}
I know that I had to miss samething easy, but I'm not able to find useful sample on Google. Thank you!
I finally found a reason of this issue.
Because the whole solution is new, it was using ./express database (I don't know why it chose exactly this instance... maybe it's default). And even if I have installed MS SQL 2012, instance of ./express is SQL2005 -> no hierarchyId support. When I specified connection string explicitly to newer version, problem solved.
I'll keep this post to help others... Don't forget to vote up if you are one of them.