EF Core with cosmos issue - .net-core

I have a SQL database that I'm using currently with EF Core. I have 2 objects:
public class Contact
{
public Guid ContactGUID { get; set; }
public string Name { get; set; }
[ForeignKey("CreatedBy")]
[InverseProperty(nameof(User.ContactCreatedBy))]
public virtual User CreatedByUser { get; set; }
...
}
public class User
{
public User
{
User = new HashSet<Contact>();
}
public Guid UserGUID { get; set; }
[InverseProperty(nameof(Contact.CreatedByUser))]
public virtual ICollection<Contact> ContactCreatedBy { get; set; }
...
}
This all works fine with EF Core connected to SQL. But something I would like to do is take this object that I've grabbed and save it to a separate CosmosDB database with EF Core.
When I try to do that however, I get the following error:
Microsoft.EntityFrameworkCore: When creating the relationship between
'User.ContactCreatedBy' and 'Contact.CreatedByUser' the entity type
'Contact' cannot be set as principal.
What is the best way to get past this error? I'd rather not create a whole separate object for my cosmos database that basically looks the same but w/out all the inverseproperties/etc. Is there a way to do that, or do I have to go about the long way?

Related

Circular Reference with Include in .NET Core

I am using code like below in .NET core
.Include(p => p.Company).ThenInclude(p => p.Country).ToList();
My classes look like below,
public partial class Company
{
public Guid Id { get; set; }
public string Name { get; set; }
public virtual Country Country { get; set; }
}
public partial class Country
{
public Country()
{
Companies = new HashSet<Company>();
}
public Guid Id { get; set; }
public string Name { get; set; }
public string ShortCode { get; set; }
public virtual ICollection<Company> Companies { get; set; }
}
And I want only Company and then Country in side the company to be populated. But I am getting the Company inside the Country and then Country in those Companies and so on populated which is causing the response delayed.
I have already tried difference examples of Include on Google/StackOverFlow.
This isn't actually a problem. EF has what's called "object fix-up". Internally, it uses an object cache. When it builds entity instances for database query results, it adds those to the object cache, allowing it to then pull out those objects later, rather than issuing the same queries again.
Because of this object cache, if it already existing entity instances corresponding to a relationship, it will auto-fill that relationship from the object cache. It's not issuing a series of circular queries forever.

Update Azure mobile app Asp.Net backend database

I have an Azure mobile app with an ASP.NET backend. I want to add a new column to an existing table. I have added the property and redeployed the service but this does not create the column in the table and gives me an error. I also tried to add the column manually with SQL management studio and kept the property in the DataObject class but this still errored. Please could you advise how I can add a new field to the mobile app database.
public class Petrol: EntityData
{
public int Mileage { get; set; }
public DateTime PurchaseDate { get; set; }
public float Quantity { get; set; }
public Decimal Cost { get; set; }
public string Station { get; set; }
public string Claim_Id { get; set; }
[ForeignKey("Claim_Id")]
public virtual Claim Claim { get; set; }
//This is the new column I would like to add
public string PhotoUrl { get; set; }
}
I have ran the Enable-Migrations command in Package Manager Console, but I am getting an error about the connection string.
The schema of your database is only deployed when your database is empty.
For a database already containing tables you have to implement code first migrations as described here: Implementing Table Controllers

Unable to establish One to Many Relations in MVC 6 Views

As a learning exercise, I was trying to form a simple One to many Relation between Vendors and Shops where each Vendor has multiple shops.
Using two model classes I achieved the following:
This is what scaffolding gives me for Shops
Why am I not getting a drop down here?
Not sharing any code as of now. As most of it is auto generated. Let me know if someone would like me to paste the code for my models.
Another doubt why are my table Columns alphabetically Ordered? If I am not mistaking entity framework 6 used to order it as per the class definition. Is there a way to override it? Cause the view scaffold seems to mirror the DB in terms of ordering objects.
Thanks.
Update:
I added a property Vendorid in the Shops Class. Now I see the Dropdown but no values. Do I need to get down to Fluent API for achieving this?
public class Shops
{
public int Id { get; set; }
public String Name { get; set; }
public int Rank { get; set; }
public String Address { get; set; }
public Boolean Active { get; set; }
public int VendorId { get; set; }
public Vendors Vendor { get; set; }
}
Vendors
public class Vendors
{
public int Id { get; set; }
public String Name { get; set; }
public int Rank { get; set; }
public Boolean Active { get; set; }
public ICollection<Shops> Shops { get; set; }
}
Env: Visual Studio 2015 (Latest ASP.net Patch Applied).
Project Template: Web Application
This depends on what approach on EF you are using. Are you sure they have relationship in their classes? If your using code first, you have to map it manually using fluent API. on OnModelCreating method on DbContext class, use something like this
modelBuilder.Entity().HasMany(v => v.Shop).WithOptional(s => s.Vendor).
If your using Database First, just create relationship on tables diagram(or script) and update the model on your project and EF will create it for you.

EF5 Code-First - Create new table

I'm working with asp.net mvc3 & Entity Framework5.
My database has been designed with the Code-First.
Entity Code
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
public class EFDbContext : DbContext
{
public DbSet<User> Users { get; set; }
}
Create DB Option
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<EFDbContext>());
I use this option, the database has been created.
After the database has been created, I need a Role table was.
So I had to modify the code as follows.
Entity Code
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Role
{
public int Id { get; set; }
public string Name { get; set; }
}
public class EFDbContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
}
I use Create DB Option again.
In this case, the existing Users table will be deleted after regeneration.
I would like to be added to the Role table, but leave data in the table Users.
What should I do?
Use Code-First Migrations.
Database.SetInitializer(null);
Then in Package Manager Console write:
add-migration addedRoles
If you did't enabled migrations before, You must enable it first:
enable-migrations
and last:
update-database
Complete guid:
http://msdn.microsoft.com/en-US/data/jj591621
Edit
If you want the database to be upgraded automatically whenever you run the application, you can use MigrateDatabaseToLatestVersion initializer:
Database.SetInitializer(new MigrateDatabaseToLatestVersion<EFDbContext, Configuration>());
Learn how migrations work.
http://msdn.microsoft.com/en-us/data/jj591621.aspx
They have another initializer, MigrateDatabaseToLatestVersion. In contrast to the one you use, this one will automatically upgrade your database to latest version without recreating the whole database.

EF Code First using non-Primary key to create one-to-many relationship

I have the following two entities:
public class User
{
public int PKID { get; set; }
public string Login { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public virtual ICollection<AppAccess> AppAccessList { get; set; }
}
public class AppAccess
{
public int PKID {get; set; }
public string Login { get; set; }
public string AppCode { get; set; }
}
The PKID field is the primary key and identity column of each table but the Login field is what links them in a one-to-many relationship where the User is the principal entity.
How can I setup the navigation property AppAccessList using the fluent API, if it is even possible, to use the Login field as the relationship key? BTW, the entities are based on existing schema that cannot be refactored at this time.
I don't believe this is possible out of the box, certainly not the ability to add a navigation property. I tried using the new power tools to reverse engineer a database and it just ignored the relationship, neither could i create it using code (annotations or fluent interface).
You can create the relationship using raw sql on the on OnModelCreating method to make the constraint, but you'd need to use join's manually to navigate between the tables.

Resources