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

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.

Related

Why is Entity Framework looking for the wrong foreign key column?

I've seen various questions on related topics, which seem like they would address my issue, but nothing I try seems to help.
I have an EF (6.1.3) model of an existing DB, which has been working fine. I've just added an additional column to a table, which represents a new relationship. Perhaps relevantly, the relationship is the second one between the two tables - the original Location is now joined by ActualDirectSite, both of them relating the Uniform and Location tables.
The moment I added the two new properties, ActualDirectSiteID and ActualDirectSite, my SELECT queries started failing with the error "Invalid column name 'Location_ID'". It's true that that column doesn't exist, but I don't see why EF is looking for it - it was happy before, but something has made it think the column name should be different. The failing name makes me think it's the original Location which is somehow no longer working.
Here's the Entity in question:
public partial class Uniform
{
public int ID { get; set; }
[Column("LocationID")]
public int? LocationID { get; set; }
[ForeignKey("LocationID")]
public virtual Location Location { get; set; }
public int? ActualDirectSiteID { get; set; }
[ForeignKey("ActualDirectSiteID")]
public virtual Location ActualDirectSite { get; set; }
}
And my (shortened) table def:
CREATE TABLE [dbo].[Uniforms](
[ID] [int] IDENTITY(1,1) NOT NULL,
[LocationID] [int] NULL,
[ActualDirectSiteID] [int] NULL)
The obvious solution to relying on convention causing incorrect assumptions about column names is to specify them explicitly, and so I've tried using Column annotations, and also to make sure that the ID and navigation properties know about each other using ForeignKey, but no dice. Any ideas?
EDIT: added missing LocationID field (already present in full code)
EDIT2: to be clear, before I added ActualDirectSiteID to the Entity it all worked fine, with no annotations required. I've just had another look at the generated SQL, and it seems like the Location_ID reference corresponds to the ActualDirectSite property:
//[Extent1] is "Uniform"
... , [Extent1].[LocationID] AS [LocationID], [Extent1].[ActualDirectSiteID] AS [ActualDirectSiteID], [Extent1].[Location_ID] AS [Location_ID], //...[Extent4] begins
EDIT3: I didn't include any of my Location entity, here it is:
[Table("Location")]
public partial class Location
{
public int ID { get; set; }
public virtual ICollection<Uniform> Uniforms { get; set; }
}
As noted in the comments: with multiple navigation properties to the same table, EF will get confused as to which navigation property refers to which inverse navigation property and ignore the FK mapping of those. A similar issue I stumbled across some time ago can be found in this SO question.
There are only two ways (I know of) to fix this issue:
Ignore at least all but one of the navigation properties with [NotMapped] or .Ignore() or
Add a inverse navigation property to (at least) all but one navigation properties to this table and adjust the mapping accordingly.
Actually, this behavior smells like a bug on EF side (from a DB point of view, I don't see the problem there), but the workaround is simple enough.
By convention every foreign key declaration include 2 properties.
If you create link to Location entity, then you must add property with name - LocationId type int. That is why you got an error
ForeignKey annotation is used to specify the name of used int id property for link (if you plan to use different name)
You can declare foreign key only like here:
public Location Location {get; set;}
public int LocationId {get; set;}
Or like here:
[ForeignKey("CustomIdProperty")]
public Location Location {get; set;}
public int CustomIdProperty {get; set;}
(Pardon me for possible typos - writting from phone)

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

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;
}

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; }

Is there a known issue with Code First default mapping on a table with 'Statuses' suffix

I have the following code in my context, and no explicit table-class mapping, yet my database keeps getting created (by my DropCreateDatabaseIfModelChanges initializer) with an EmployeeStatus table, not EmployeeStatuses. Is there a known issue with this, or am I going insane or what?
public DbSet<Department> Departments { get; set; }
public DbSet<EmployeeStatus> EmployeeStatuses { get; set; }
All my other tables are named exactly after their DbSet names, as I expect.
Entity Framework uses its pluralization service to infer database table names based on
the class names in the model—Destination becomes Destinations, Person becomes
People, etc. By convention, Code First will do its best to pluralize the class name and use the results as the name of the table. However, it might not be the same as your
table naming conventions.
You can use the Table Data Annotation to ensure that Code First maps your class to
the correct table name.

how to generate a database table from an entity type?

How to create an entity type and then generate a database table from it?
I know this feature was not supported two years ago in EF, what about now?
You've got 2 options:
Entity Framework Model First where you create the model first and then generate the database from that or
Entity Framework Code First where you create normal Poco objects and generate the database from that.
I've personally used Entity Framework Code First for MVC development and it works like a charm, it really is an awesome feature and easy to use.
Now, Entity Framework introduced these feature.
Basically, with only two steps is sufficient for this, please see below steps to go:
Create your Entity
public class Resturant
{
public int ID { get; set; }
public string Name { get; set; }
}
Create Context class
public class OdeToFoodDb: DbContext
{
public DbSet<Resturant> Resturants { get; set; }
}
However, you may need more coding in Global.ascx for advance options but these are the basic steps.
A database named "OdeToFoodDb" will create and a table named "Resturant" also will create by these steps.