.Net Core AddDbContext - c#

I has the following codes in my AddDbContext.
services.AddDbContext<RewardsContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MembershipContext"),
b => b.UseRowNumberForPaging(), sqlServerOptions => sqlServerOptions.CommandTimeout(60)), ServiceLifetime.Scoped);
But how can I include sqlServerOptions.CommandTimeout(60) in my line of codes as well? It keep giving me error. I suspected there's typo error.

Call CommandTimeout on the same instance of sqlServerOptionsAction parameter you are using to configure the row paging:
services.AddDbContext<RewardsContext>(
options =>
options.UseSqlServer(Configuration.GetConnectionString("MembershipContext"),
b => b.UseRowNumberForPaging().CommandTimeout(60)),
ServiceLifetime.Scoped);

Related

How to ignore null values in C# Automapper

I am using Automapper in C#.
Currently I am trying to map using below code.
CreateMap<Student, StudentDto>()
.ForMember(dest => dest.FeeType, opt =>
{
opt.PreCondition(src => (src.Key == "Paid"));
opt.MapFrom(src => src.Value);
});
I want to map only if the key == Paid else it should not map. However in this case , it is just passing null.
So lets say if the collection has 100 records and only 1 matches the condition other 99 records are passed as NULL.
Edit -- I am using Azure Function Apps and my Automapper version is 10.0.0
Please advise.
I think you have to update your ConfigureServices like=>
public void ConfigureServices(IServiceCollection services) {
// Auto Mapper Configurations
var mappingConfig = new MapperConfiguration(mc => {
mc.AddProfile(new MappingProfile());
});
IMapper mapper = mappingConfig.CreateMapper();
services.AddSingleton(mapper);
//This line should be updated
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1).AddJsonOptions(options => options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore);
}
.AddJsonOptions(options => options.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore); ofNewtonsoft.Json.NullValueHandling.Ignore, It will handle what you ask for.
Note: Please check the link of a documentation. I believe it will do the trick.
LINK

Entity Framework Core Many to Many change navigation property names

I have a table called "LogBookSystemUsers" and I want to setup many to many functionality in EF Core 5. I almost have it working but the problem is my ID columns are named SystemUserId and LogBookId but when EF does the join it tries to use SystemUserID and LogBookID. This is my current configuration code:
modelBuilder.Entity<SystemUser>()
.HasMany(x => x.LogBooks)
.WithMany(x => x.SystemUsers)
.UsingEntity(x =>
{
x.ToTable("LogBookSystemUsers", "LogBooks");
});
I tried this:
modelBuilder.Entity<SystemUser>()
.HasMany(x => x.LogBooks)
.WithMany(x => x.SystemUsers)
.UsingEntity<Dictionary<string, object>>("LogBookSystemUsers",
x => x.HasOne<LogBook>().WithMany().HasForeignKey("LogBookId"),
x => x.HasOne<SystemUser>().WithMany().HasForeignKey("SystemUserId"),
x => x.ToTable("LogBookSystemUsers", "LogBooks"));
But that just adds two new columns instead of setting the names of the current columns.
This is all database first. I don't want to have to use a class for the many to many table because I do this all over in my project and I don't want a bunch of useless classes floating around. Any ideas?
Interesting bug, consider posting it to EF Core GitHub issue tracker.
By idea what you have tried should do it
modelBuilder.Entity<SystemUser>()
.HasMany(x => x.LogBooks)
.WithMany(x => x.SystemUsers)
.UsingEntity<Dictionary<string, object>>("LogBookSystemUsers",
x => x.HasOne<LogBook>().WithMany().HasForeignKey("LogBookId"),
x => x.HasOne<SystemUser>().WithMany().HasForeignKey("SystemUserId"),
x => x.ToTable("LogBookSystemUsers", "LogBooks"));
And it works for any other FK property names except the {RelatedEntity}Id when related entity PK property is called ID.
As workaround until it gets fixed, define explicitly the desired join entity properties before configuring the relationship:
// add this
modelBuilder.SharedTypeEntity<Dictionary<string, object>>("LogBookSystemUsers", builder =>
{
builder.Property<int>("LogBookId");
builder.Property<int>("SystemUserId");
});
// same as the original
modelBuilder.Entity<SystemUser>()
.HasMany(x => x.LogBooks)
.WithMany(x => x.SystemUsers)
.UsingEntity<Dictionary<string, object>>("LogBookSystemUsers",
x => x.HasOne<LogBook>().WithMany().HasForeignKey("LogBookId"),
x => x.HasOne<SystemUser>().WithMany().HasForeignKey("SystemUserId"),
x => x.ToTable("LogBookSystemUsers", "LogBooks"));

Return an object in C#

I have a method that gets a list of people from the database using aspnet boilerplate framework. Since adding the include line I get the error message:
Specified cast is not valid
Here is the full error message:
Specified cast is not valid
Here is the c# method:
public ListResultDto<PersonListDto> GetPeople(GetPeopleInput input)
{
var persons = _personRepository
.GetAll()
.Include(p => p.Phones)
.WhereIf(
!input.Filter.IsNullOrEmpty(),
p => p.Name.Contains(input.Filter) ||
p.Surname.Contains(input.Filter) ||
p.EmailAddress.Contains(input.Filter)
)
.OrderBy(p => p.Name)
.ThenBy(p => p.Surname)
.ToList();
return new ListResultDto<PersonListDto>(ObjectMapper.Map<List<PersonListDto>>(persons));
}
Any ideas on what I need to do to resolve the issue?
I think its cannot be break on .Include(p => p.Phones) line. Because there is nothing about casting. You considered about constructor of the ListResultDto class can take ObjectMapper.Map<List<PersonListDto>> as parameter. Also maybe you need to change that line with ObjectMapper.Map<ListResultDto<PersonListDto>>

EF Core Fluent API - unique constraint not being detected/included in migration

I am trying to add a unique constraint on two columns. I found multiple sources declaring that I should be using HasAlternateKey method for EF Core Fluent API applications. However, after running Add-Migration, the code that is generated in the migration files does not include the constraint - almost as if its being purposely ignored or not detected.
Here is the ModelBuilder code that I am using:
modelBuilder.Entity<PlasmidStockCode>(e =>
{
e.ToTable("PlasmidStockCode");
e.HasKey(c => c.ID);
e.Property(c => c.ID).ValueGeneratedOnAdd();
e.HasAlternateKey(c => new { c.ClientName, c.PlasmidName });
e.HasMany(c => c.PlasmidStockComments).WithOne().HasForeignKey(c => c.PlasmidStockCodeID).OnDelete(DeleteBehavior.Restrict);
e.HasMany(c => c.PlasmidStockLots).WithOne().HasForeignKey(c => c.PlasmidStockCodeID).OnDelete(DeleteBehavior.Restrict);
e.HasMany(c => c.qPCRTargets).WithOne().HasForeignKey(c => c.PlasmidStockCodeID).OnDelete(DeleteBehavior.Restrict);
});
AddBaseConfiguration(modelBuilder);
}
I've also attempted to use .HasIndex, but unfortunately, is not being detected/included either.
Any idea as to what I may be missing? Thanks in advance!
Use IsUnique and HasIndex methods in you DBContext class's OnModelCreating method to add the composite key to your table. Then add migration using Add-Migration <YourMigrationName> and then run Update-Database in Program Manager Console.
modelBuilder.Entity<PlasmidStockCode>(b =>
{
b.HasIndex(e => (new { e.ClientName, e.PlasmidName })).IsUnique();
});
I did something similar and it seems to work just fine:
builder.Entity<AccountUser>().HasAlternateKey(c => new { c.a, c.b });
The constraint is added to the Up method of the generated migration file
migrationBuilder.AddUniqueConstraint(
name: "AK_Users_a_b",
table: "Users",
columns: new[] { "a", "b" });

C# Moq how to setup EF DbContext extension method ToList() to return mock.Object.Tolist()

I'm trying to mock Entity Frameworks DbContext using Moq and in particular its extension methods Add(), Tolist() and Find().
I need the Find() and ToList() methods to actually return values stored in my mockContext.Object.
I've created my DbSet and set following properties:
var mockTickets = new Mock<DbSet<Ticket>>();
mockTickets.As<IQueryable<Ticket>>().Setup(m => m.Provider).Returns(tickets.Provider);
mockTickets.As<IQueryable<Ticket>>().Setup(m => m.Expression).Returns(tickets.Expression);
mockTickets.As<IQueryable<Ticket>>().Setup(m => m.ElementType).Returns(tickets.ElementType);
mockTickets.As<IQueryable<Ticket>>().Setup(m => m.GetEnumerator()).Returns(() => tickets.GetEnumerator());
I've created my DbContext with the following property
var mockContext = new Mock<SupportCenterDbContext>();
mockContext.Setup(m => m.Tickets).Returns(mockTickets.Object);
Now I'm trying to test the following methods
mockContext.Object.Tickets.Add(Ticket ticket)
returns Ticket t
mockContext.Object.Tickets.ToList<Ticket>()
returns IEnumerable tickets
mockContext.Object.Tickets.Find(int ticketNumber)
returns Ticket t
I've tried the following code but get "Invalid setup on an extension method".
mockContext.Setup(x => x.Tickets.Add(It.IsAny<Ticket>())).Returns(It.IsAny<Ticket>());
mockContext.Setup(x => x.Tickets.ToList()).Returns(mockTickets.Object.ToList());
mockContext.Setup(x => x.Tickets.Find(It.IsAny<int>())).Returns(It.IsAny<Ticket>());
These are my assertions for the Add() and ToList() methods
//ToList
Assert.AreEqual(result.Count(), mockContext.Object.Tickets.Count());
Assert.IsInstanceOfType(result, typeof(IEnumerable<Ticket>));
//Add
Assert.IsInstanceOfType(result, typeof(Ticket));
mockContext.Verify(x => x.Tickets.Add(It.IsAny<Ticket>()), Times.Once());
mockContext.Verify(x => x.SaveChanges(), Times.Once());
EDIT
I'm a step closer by removing mockContext.Setup(x => x.Tickets.ToList()).Returns(mockTickets.Object.ToList());.
and adding the following
mockContext.Setup(x => x.Tickets.Add(It.IsAny<Ticket>())).Returns<Ticket>(x => x);
mockContext.Setup(t => t.Tickets.Find(It.IsAny<int>())).Returns<int>(x => mockContext.Object.Tickets.Find(x));
This last line still doesn't produce the desired output. Is it not possible to pass the value of the input parameter to the Find() method in the Returns() section?
Thanks in advance for any help.
You can't mock extension methods, and it is not a common practice to mock the DBContext.
A better idea would be to use an in-memory data context and populate it with test data, as described here: https://learn.microsoft.com/en-us/ef/core/miscellaneous/testing/in-memory

Categories