How to Exclude from migration Auto-Generated table in EF? - entity-framework

i have table Asp_net_users which is many-to-many relation with table Clients. There are no mapped object in between them, it been auto -generated by EF:
modelBuilder.Entity<Client>(entity =>
{
entity.Property(e => e.State)
.HasConversion<string>();
entity.HasMany(d => d.Users)
.WithMany(p => p.Clients)
.UsingEntity<Dictionary<string, object>>(
"ClientUser",
l => l.HasOne<AspNetUser>().WithMany().HasForeignKey("UserId"),
r => r.HasOne<Client>().WithMany().HasForeignKey("ClientId"),
j =>
{
j.HasKey("ClientId", "UserId");
j.ToTable("client_users"); // ,"identity"
j.IndexerProperty<string>("ClientId");
j.IndexerProperty<string>("UserId");
});
});
The code above generating table client_users which i don't want in my migration.
I've tried to add to code above:
.Metadata
.SetIsTableExcludedFromMigrations(true)
no luck.
I know I can exclude using this method
modelBuilder.Entity<AspNetUser>().ToTable("asp_net_users", "identity", t => t.ExcludeFromMigrations());
but the problem is: above mentioned table is auto generated and I don't know how to do ToTable on it.
tried
modelBuilder.Entity().ToTable("client_users", t => t.ExcludeFromMigrations());
but it don't compile. modelBuilder.Entity() wants to have an object.
Please help

I added j.Metadata.SetIsTableExcludedFromMigrations(true); inside and it worked:
entity.HasMany(d => d.Users)
.WithMany(p => p.Clients)
...
j =>
{
...
j.Metadata.SetIsTableExcludedFromMigrations(true);
});

Related

Foreign key object is getting "instance is already tracked" error in unit tests

In the screenshot below, I'm trying to attach an Answer object so that it can be updated. However, this causes the error: "The instance of entity type 'QuestionSet' cannot be tracked because another instance with the key value '{QuestionSetId: 3}' is already being tracked."
The QuestionSet is indeed being tracked, so I don't think I'm confused about that part. However this error doesn't make sense to me, since I'm trying to update the Answer record, not the QuestionSet record. Shouldn't the contents of the QuestionSet field be irrelevant? I'm not trying to perform an operation that affects the related QuestionSet record, so why am I getting this error?
It's important to note that this error is ONLY happening when I run unit tests. The code works just fine outside of unit tests.
Here's the context setup code I'm using for my unit tests:
DbContextOptions<SurveyApplicationDbContext> options = new DbContextOptionsBuilder<Infrastructure.Data.EntityFramework.SurveyApplicationDbContext>()
.EnableSensitiveDataLogging()
.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
.UseInMemoryDatabase(databaseName: "SurveyApplicationDbContext" + dbNameSuffix).Options;
var context = new SurveyApplicationDbContext(options);
context.Survey.Add(new Survey
{
SurveyId = 123,
ClubId = "c1",
FormId = 1,
CreateDateUtc = DateTime.Now
});
context.Answer.Add(new Answer
{
SurveyId = 123,
QuestionSetId = 3,
AnswerValue = "Answer Value",
});
context.QuestionSet.Add(new QuestionSet
{
QuestionSetId = 3,
QuestionId = Constants.ScoreQuestionId,
SectionId = Constants.SummarySectionId,
FormId = 1
});
context.SaveChanges();
_mockSurveyUnitOfWork.Setup(x => x.SurveyRepository).Returns(new SurveyRepository(context));
_mockSurveyUnitOfWork.Setup(x => x.AnswerRepository).Returns(new AnswerRepository(context));
_mockSurveyUnitOfWork.Setup(x => x.QuestionSetRepository).Returns(new QuestionSetRepository(context));
}
And here is my DbContext model setup code for Answer:
modelBuilder.Entity<Answer>(entity =>
{
entity.ToTable("answer");
entity.HasIndex(e => new { e.QuestionSetId, e.SurveyId })
.HasName("UCanswer_questionSetId-surveyId")
.IsUnique();
entity.Property(e => e.AnswerId).HasColumnName("answerId");
entity.Property(e => e.AnswerValue)
.HasColumnName("answerValue")
.HasMaxLength(800)
.IsUnicode(false);
entity.Property(e => e.CreateDateUtc)
.HasColumnName("createDateUTC")
.HasColumnType("datetime");
entity.Property(e => e.ModifiedDateUtc)
.HasColumnName("modifiedDateUTC")
.HasColumnType("datetime");
entity.Property(e => e.QuestionSetId).HasColumnName("questionSetId");
entity.Property(e => e.ScoreValue)
.HasColumnName("scoreValue")
.HasColumnType("decimal(3, 2)");
entity.Property(e => e.SurveyId).HasColumnName("surveyId");
entity.HasOne(d => d.QuestionSet)
.WithMany(p => p.Answer)
.HasForeignKey(d => d.QuestionSetId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FKanswer_questionSet_questionSetId");
entity.HasOne(d => d.Survey)
.WithMany(p => p.Answer)
.HasForeignKey(d => d.SurveyId)
.OnDelete(DeleteBehavior.ClientCascade)
.HasConstraintName("FKanswer_survey_surveyId");
});
Obviously there's more code involved that could be causing this error, but I didn't want to overload this post with too much code. Please let me know if I should provide more details. Mainly I want to understand this error on a conceptual level: why is it complaining about tracking QuestionSet even though I'm not trying to update it?

Error upgrating to Entity Framework Core 3: RelationalReferenceCollectionBuilderExtensions does not exist in the current context

Im upgrating from Entity Framework Core 2 to Entity Framework Core 3. And I have this error:
Error CS0103 The name 'RelationalReferenceCollectionBuilderExtensions'
does not exist in the current context
The error is on method OnModelCreating(ModelBuilder modelBuilder), this is the code:
modelBuilder.Entity<Person>(entity =>
{
//some props
RelationalReferenceCollectionBuilderExtensions.HasConstraintName((ReferenceCollectionBuilder)entity
.HasOne(d => d.RuleCodeNavigation)
.WithMany(p => p.Person)
.HasForeignKey(d => d.RuleCode)
.OnDelete(DeleteBehavior.ClientSetNull), "FK_Person_Rules");
});
It seems the class RelationalReferenceCollectionBuilderExtensions does not exist in EF Core 3.
Any idea how I can fix this?
Not sure what happened to RelationalReferenceCollectionBuilderExtensions, but the suggested method to name your constraints is this
modelBuilder.Entity<Person>(entity =>
{
//some props
entity
.HasOne(d => d.RuleCodeNavigation)
.WithMany(p => p.Person)
.HasForeignKey(d => d.RuleCode)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK_Person_Rules");
});

Linq include nested collection and orderby

I have nested entities like Property -> Facility -> Farm -> License etc.
I want to get the most recent license and my original query looks like this.
return _db.Properties
.Include(c => c.Contact)
.Include(f => f.Facilities.Select(c => c.Contact))
.Include(f => f.Facilities.Select(ff => ff.Farms.Select(s => s.Species)))
.Include(x => x.Facilities.Select(l => l.Licenses))
.SingleOrDefault(x => x.PropertyID == id);
Since I want to get the most recent license I tried
return _db.Properties
.Include(c => c.Contact)
.Include(f => f.Facilities.Select(c => c.Contact))
.Include(f => f.Facilities.Select(ff => ff.Farms.Select(s => s.Species)))
.Include(x => x.Facilities.Select(l => l.Licenses.OrderByDescending(d => d.IssueDate)))
.SingleOrDefault(x => x.PropertyID == id);
which fails of course because you cant use an orderby clause there.
If I try an orderby clause at the end of the linq it will start at Property and I will need to drill down to the licenses again.
What is the preferred convention for this?
--EDIT--
Based on Robert's suggestion I flipped the query to get the Licenses first but I guess I need to do some projection since this query only gives me the Property entity and no child entities.
return _db.Licenses.OrderByDescending(x => x.IssueDate)
.Include(f => f.Facility)
.Include(f => f.Facility.Property)
.Include(f => f.Facility.Property.Contact)
.Include(c => c.Facility.Contact)
.Include(f => f.Facility.Farms)
.Include(f => f.Facility.Farms.Select(s => s.Species))
.Where(x => x.Facility.Property.PropertyID == id)
.Select(x => x.Facility.Property).SingleOrDefault();
Any ideas to get all children?

multiple tables mapping entity framework code first

I have 3 Entities Roles, Modules and Permissions and I am following code first approach using EF 6
Roles has RoleID , Modules has ModuleID and Permissions has PermissionID as Keys.
Now I want Map these 3 ID values to another mapping table RoleAccess on creating Role
I am able to map entity to with ICollection property and the same is not working for the above scenario.
help me out with code suggestions...
The configuration i am trying add is below..
'this is the mapping configuration i am trying `this.ToTable("Roles");
//this.HasKey(c => c.Id)
// .HasMany(c => c.Permissions)
// .WithRequired()
// .HasForeignKey(c => new { c.SubModuleId, c.EntitlementTypeId });
this.HasMany(a => new[] {a.SubModules,a.EntitlementTypes})
.WithMany(b => b.Roles)
.Map(mc =>
{
mc.ToTable("Permissions");
mc.MapLeftKey("RoleId");
mc.MapRightKey(new[] { "SubModuleId", "EntitlementTypeId" });
});`'

Linq To Sql Entity Framework Getting Nested Entities

I'm trying to do an include of a nested entity. I assumed the below code would work but it does not recognize the CapitalMailOrders entitycollection. Can anyone point me in the right direction to include these?
var result = db.Contacts
.Include(a => a.IDXPageLinks)
.Include(b => b.ReboGatewayLoginInfoes)
.Include(c => c.SocialMedias)
.Include(d => d.WebSiteInfoes)
.Include(e => e.ContactImages)
.Include(f => f.RealtorSetUpProcesses)
.Include(h => h.RealtorSetUpProcesses.CapitalMailOrders) // getting compile time error here. Doesn't recognize Entity
.Include(g => g.Contact_CarrierCode_Assignments)
.FirstOrDefault(c => c.ContactID == id);
Thanks
The extra entity level is accessed from a collection and so you need to add a Select in order to bring all the entries into the include.
.Include(h => h.RealtorSetUpProcesses.Select(h2 => h2.CapitalMailOrders)