EF core cosmos Foreign key - entity-framework-core

I am working with EF core and Azure Cosmos DB. I have a problem with the foreign keys.
When I load an entity, the related classes are not being loaded.
For example, I want to select a user with its roles. It's connected to Users, Tenants, and Roles containers. The data is loaded, but the relations are not loaded:
I tried different ways of one-one/one-many relations.
The last config for the relations is:
var tenantUserModel = modelBuilder.Entity<TenantUser>();
tenantUserModel.ToContainer(nameof(TenantUsers))
.HasNoDiscriminator()
.HasPartitionKey(tu => tu.TenantId)
.HasKey(tu => new {tu.TenantId,tu.UserId,tu.RoleId});
tenantUserModel.HasOne(tu => tu.User).WithMany().HasForeignKey(tu=>tu.UserId);
But it doesn't load the relation.

Related

Entity Framework: auto-generate primary keys after initializing tables

I'm using Entity Framework (6) in a code-first arrangement to create a database and pre-populate it from a set of CSV files. Because the tables are coming from another application, they already have primary keys, and relationships embedded in the data make reference to those keys.
For that reason I've been using [DatabaseGenerated(DatabaseGeneratedOption.None)] when defining these tables, so that the PKs already in place get used.
However, after the data have been imported, I want to be able to add new records to the tables. How do I get the DB to assign new sequential PKs for the new records?

EF code first migration - one-to-many to many-to-many

I have entities User and DiscussionThread and I need to create many-to-many relationship but I forgot to put a ICollection in User entity, so Code First created a one-to-many relationship.
I wonder if there is a way how to migrate this relationship to many-to-many. I tried following things, but nothing helps:
I added ICollection to User entity
I added modelBuilder.Entity().HasMany(t => t.NotificationSubscribedUsers).WithMany(u => u.SubscribedThreadNotifications) to configuration
I tried generate new migration (using Add-Migration), but migration is empty
No DB tables were created/updated and EF still uses a one-to-many relationship...

How to clear many to many relationship without loading from database in EF?

I have the following entities (pocos using Entity Framework 5):
Company: Id, Name, Applications, etc.
Application: Id, Name, etc.
There's a many-to-many relationship between companies and applications.
Having a company (without the apllications relationship loaded from the database) and a collection of application ids, I would like to clear the applications from the company and add the applications with ids specified in the collection.
I can attach applications using their ids, without loading them from the database, like this:
foreach (int id in selectedApplications)
{
Application application = new Application() { Id = id };
_context.Applications.Attach(application);
company.Applications.Add(application);
}
_context.SaveChanges();
But I need to clear the applications relationship first. Is there any way to clear a many-to-many relationship without loading it from the database first?
This is only way. company.Applications must be loaded when you add or remove items from it, otherwise the change tracker will never be aware of any changes.
Also, the junction table is not an entity in the conceptual model, so there is no way to set primitive foreign key properties as is possible in foreign key associations. You have to access the associations by the object collections.

EntityFramework Join table with more than 2 entities

I have 4 tables/entities which fall into two groups, alerts and recipients. Either entity from a group can map to either entity of the other group (an Alert can have many Recipients and RecipientGroups and so on).
Tables:
Alerts
AlertGroups (1 to many relationship with alerts)
Recipients
RecipientGroups (many to many relationship with recipients)
Instead of making 4 jointables (AlertRecipients, AlertRecipientGroups, etc.) I want to make one join table with 4 columns, each column being a nullable FK for one of my entity types.
I've made the table in SQL, and set up my context using Fluent API like so:
modelBuilder.Entity<AlertGroup>()
.HasMany(ag => ag.RecipientGroups)
.WithMany(rg => rg.AlertGroups)
.Map(m => m.ToTable("AlertRecipients")
.MapLeftKey("AlertGroupID")
.MapRightKey("RecipientGroupID"));
modelBuilder.Entity<AlertGroup>()
.HasMany(ag => ag.Recipients)
.WithMany(rg => rg.AlertGroups)
.Map(m => m.ToTable("AlertRecipients")
.MapLeftKey("AlertGroupID")
.MapRightKey("RecipientID"));
But I get this error:
Schema specified is not valid. Errors:
(251,6) : error 0019: The EntitySet 'AlertGroupRecipient' with schema
'dbo' and table 'AlertRecipients' was already defined. Each EntitySet
must refer to a unique schema and table.
Is there a workaround to do what I'm trying to do?
EF is not able to do that this way. With EF you need separate join table for every many-to-many relationship (because that is the way how you should do that). If you want to do that your way you cannot use many-to-many association in the mapping. You must instead "upgrade" your AlertRecipients to the real entity (another class in your model) and handle everything like one-to-many association.

The Many To Many relation will not be mapped when using ADO.net entity framework

I have these three tables inside my sql server but when mapping these tables using EF I will lose the table representing the M-M relation -the accountsitemapping table- and in this case I will not be able to know which accounts are linked to which sites.
To workaround this problem I just added a new column to the AccountSiteMapping table and I re-mapped the tables again then I can access the AccountSiteMapping table.
But is there a way to be able to solve this problem without the need to modify my table design ?
By default entity framework will hide all mapping tables in many-to-many relationships. You will have to do your queries this way:
For example, finding SiteDefinitions associated with a given org_ID:
db.SiteDefinitions.Where(a => a.AccountDefinitions.Any(b => b.ORG_ID == org_ID));