Executing stored procedure from Entity Framework 7 - c#

I'm having a procedure which simply returns data from multiple tables. I'm trying to execute this procedure from EF as follows
await _context.Database.SqlQuery<TEntity>(command).ToListAsync();
Firstly, I have created a model class with property names to match the columns returned by the SP. Removed some properties for simplification,
public partial class Inventory
{
public string? location { get; set; }
public string? Warehouse { get; set; }
public string? Company { get; set; }
public string? Item { get; set; }
}
secondly, Added DbSet property to the context class
public virtual DbSet<Inventory> Inventorys { get; set; }
Then, I'm trying to call MapToStoredProcedures on entity Inventory.
modelBuilder.Entity<Inventory>().MapToStoredProcedures();
But, MapToStoredProcedures() is not recognized. I've verified that EF 7 packages are referenced by the project. What Am I missing here?

I followed the steps in https://erikej.github.io/efcore/2020/08/03/ef-core-call-stored-procedures-out-parameters.html and was able to get it working.

Related

Entity Framework Core 3.1.2 related data not returned with .Include()

My 2 entities have a simple one-to-many i.e. parent child relationship.
public class Itinerary {
public Itinerary() {
CodeHours=new List<CodeHours>();
}
public int Id { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public DateTime DateWorked { get; set; }
public String EnteredBy { get; set; }
public List<CodeHours> CodeHours { get; set; }
}
public class CodeHours {
public int Id { get; set; }
public String Code { get; set; }
public float Hours { get; set; }
public Itinerary Itinerary { get; set; }
public int ItineraryId { get; set; }
}
public class DBContext : DbContext {
public DbSet<Itinerary> Itineraries { get; set; }
}
I am retrieving Itinerary from its DbSet like this
Itinerary itn = ctx.Itineraries.Where(i => i.FirstName == Model.FirstName
&& i.LastName == Model.LastName
&& i.DateWorked == row.Date
).Include(i => i.CodeHours)
.FirstOrDefault();
I get the correct Itinerary but its CodeHours is always empty. SQL Server Profiler indicates that CodeHours table is never included in the query curiously I see 2 separate select statements being issued to SQL Server even though I have only 1 query against the DbSet in my code.
Adding CodeHours DbSet to my DbContext makes no difference.
The app is ASP.NET MVC 5. A similar example from an EF Core 3 course works but it is a Console App and not ASP.NET MVC
Thank you in advance.
Not certain it's the cause of you're problem, but in your Itinerary class the type CodeHours is wrong. Should be:
public ICollection<CodeHours> CodeHours { get; set; }
It's okay to initialize it to a List<CodeHours> in the constructor for when you're creating new entities in memory, but when you fetch the from the DB, EF will put its own collection in there.
I managed to get the code working as-is by creating a new project from scratch and copying the relevant artifacts from the current non-working project. I think the project may have gotten corrupted when I initially added EF 6 but later on switched to using EF Core 3. Not sure if I removed EF 6 before adding EF Core 3.

Add properties to model dynamically?

I have a following model class:
public class Class1
{
public int Id { get; set; }
[StringLength(50)]
public string Name { get; set; }
}
public class MyContext : DbContext
{
public DbSet<Class1> Class1s{ get; set; }
}
Now I want to add one more property to my model that will be
public string NewProp { get; set; }
I know very well to achieve this by code , but is there any way to add this dynamically?
in simple I want to make a UI who ask me about property name as well as datatype when I submit values it automatically add the property to my existing model. I am using EntityFramework Code-First. However since I have already the DB, I can also use the DB-First approach if the solution is using DB-First.

EF Code First Migration - Property migration

So Imagine this situation:
namespace SC.BL.Domain
{
public class User
{
public String Name { get; set; }
public String Adress { get; set; }
public int PhoneNumber { get; set; }
public char Gender { get; set; }
}
}
EF Code first migration is enabled. I implemented code-based migration by using 'enable-migrations'
My DbInitializer is set to use the MigrateDatabaseToLatestVersion initializer
Now my question is, I would like to migrate one property into multiple properties, without the loss of data, after this the old property may be removed!
Suppose I have in my database the following,
Name: User1
Address: Emmalaan 2, Gelderland
PhoneNumber: 0471250950
Gender: M
Now I want to change my User class to the following:
namespace SC.BL.Domain
{
public class User
{
public String Name { get; set; }
public String StreetName { get; set; }
public int HouseNumber { get; set; }
public String City { get; set; }
public int PhoneNumber { get; set; }
public char Gender { get; set; }
}
}
So now I want that after migrations, the data in the database is changed (without dataloss) and put in the right properties.
Where can I till the migrator to do something like this?
Name: User1
StreetName: Emmalaan 2
HouseNumber: 2
City: Gelderland
PhoneNumber: 0471250950
Gender: M
Is this possible via migration? And how is this done?
I think that the only thing you could do is the editing of the generated migration to do the transformation you want.
Inside Up() method of the migration:
use the Sql() method to write the data into a temporary table
migrate the table to the new structure (with the generated code)
use the Sql() method to take all the data (splitted as you want) from the temporary table so you can fill the edited table
in the Down() method the inverse of Up().
I don't think that this is possible via migration. You want to change structure of table, and you want that migration automatically separate data in different columns. I think that this is not possible. I think that better way is to only add columns by migration and after that you can create SQL procedure for splitting and updating data to different columns.

Cannot migrate new table in asp.net because there is an existing table in code first migration

I am developing a ASP.NET MVC website. For interacting with database, I am using Entity Framework with code first approach. But now I am having a problem in adding/migrating new table and entity to my model and database.
First I created a entity class
public class Category
{
public int Id { get; set; }
[Required]
[MaxLength(40)]
public String Name { get; set; }
[MaxLength(60)]
public String MmName { get; set; }
}
But for this entity, I created database manually. I did not use any migration command. Then I run the app and register a user using built-in identity registration system. So database tables are created successfully. Then I continued development. I was working fine. After I developed everything dealing with Category, I tried to add another entity and database table.
So I created a entity class like this
public class Region
{
public int Id { get; set; }
[Required]
[MaxLength(50)]
public String Name { get; set; }
[MaxLength(70)]
public String MmName { get; set; }
[MaxLength(30)]
public String GeoLocation { get; set; }
[MaxLength(200)]
public String Description { get; set; }
[MaxLength(250)]
public String MmDescription { get; set; }
}
Then I run the following command to update database
enable-migrations
add-migration "CreateRegion"
update-database
I got this error
Here is already an object named 'Category' in the database.
This is my initiaizer class
public class ContextInitializer : System.Data.Entity.DropCreateDatabaseIfModelChanges<AyarDbContext>
{
protected override void Seed(AyarDbContext context)
{
}
}
How can I update database using command line? I want to migrate from command line because I am practising code first approach.
I see two options at this point:
1) Drop the table from the database and re run the migration. It will create both tables for you.
2) Modify the migration file so it's not trying to create the Category table. This goes against how Code First is supposed to work but you're already in that situation by having existing tables.

EF7 Code First - Property cannot exist on entity type 'object' when generating migration

Problem
When trying to create a initial migration of my EF7 Code First database by executing from the command line:
dnx ef migrations add Initial
I get the error:
System.InvalidOperationException: The property 'ExerciseTemplateId' cannot exist on entity type 'object' because the property is not marked as shadow state and no corresponding CLR property exists on the underlying type.
Full Stacktrace
Any ideas?
The Model Causing the Error
For some reason EF7 doesn't seem to like the primary key property ExerciseTemplateId on my Model:
public class ExerciseTemplate
{
public int ExerciseTemplateId { get; set; }
public string InitalCode { get; set; }
public string ClassName { get; set; }
public string MainMethodName { get; set; }
public int ExerciseForeignKey { get; set; }
public Exercise Exercise { get; set; }
}
More Detail
The only interesting part of the ExerciseTemplate model is a one to one relationship with the Exercise model:
public class Exercise
{
public int ExerciseId { get; set; }
public string Name { get; set; }
public string Guidance { get; set; }
public ExerciseTemplate Template { get; set; }
public List<ExerciseCategory> Categories { get; set; }
public List<Test> Tests { get; set; }
}
This question is already long so my DBContext is in this DBContext Gist
Update
All the Models and the DB Context can be found at this Models and Context Gist
Long story short: do not use object or Type as property type in your model classes. It has no representation in the database.
If you absolutely need to store arbitrary objects, you may use some serializer and store the serialized objects as BLOB in the database.

Categories