What Scaffolding Nuget package for child collections - entity-framework

I am using VS2015 and have MVC5 web app. I want to use scaffolding feature to generate CRUD for my child entities: currently when generating the scaffolding it is NOT creating the views/edit/create for the IEnumerable collection 'Cities'.
I have googled but not found anything. Is there a Nuget package that does what I want. It should allow to add/delete/edit the cities maybe using partial view but should be auto-generated.
code:
public partial class Country
{
public int ID { get; set; }
public string Name { get; set; }
public string Color { get; set; }
public string Location { get; set; }
public virtual IEnumerable<Cities> Cities { get; set; }
}
public partial class Cities
{
public int ID { get; set; }
public string Name { get; set; }
public string TreLocation { get; set; }
public string Geo { get; set; }
}

Do you want an editable list of cities under each country?
Don't use mvc! In the time you spend figuring it out, you can probably learn angular. Which is far better for tis sort of thing.
However, back in the mists of time wise sages wrestled with this problem, for example....
Collection of complex child objects in Asp.Net MVC 3 application?
https://www.donnfelker.com/editable-grid-list-binding-in-mvc2/&ved=2ahUKEwiltefd9cngAhWjQxUIHe45AM4QFjACegQIARAB&usg=AOvVaw2z8iH5hZnObcnIMl3d4cyI

Related

How to generate user specific instances of an exam object with unique questions

I'm creating an online examination system where I have an exam with a list of questions and need to generate a unique instance/record for each user taking the exam. The questions in each instance are not the same but can contain variations (different answers, different blank spaces to fill in. etc.)
The exam will be created for eg. 10 users and I need to create 10 unique variations of the exam. I am struggling with how to best model this exam instance in my application.
I am using a .NET Core API with Entity Framework and a PostgreSQL DB. This is what my Exam model looks like right now
// This is what the teacher creates - a template
public class Exam
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Status { get; set; }
[Required]
public DateTime StartDate { get; set; }
[Required]
public DateTime EndDate { get; set; }
[Required]
public Semester Semester { get; set; }
[Required]
public ICollection<Question> Questions { get; set; }
public ICollection<Tag> Tags { get; set; }
public Exam(){
this.Tags = new List<Tag>();
this.Questions = new List<Question>();
}
}
And I thought of creating something like this for the Exam Instance
// This is what the student receives to complete - a specific instance
public class ExamInstance
{
[Key]
public int Id { get; set; }
[Required]
public Exam Exam { get; set; }
[Required]
public ICollection<QuestionInstance> QuestionInstances { get; set; }
[Required]
public User User { get; set; }
public ExamInstance(Exam exam, User user)
{
this.Exam = exam;
this.User = user;
this.QuestionInstances = new List<QuestionInstance>();
GenerateQuestionInstances();
}
private void GenerateQuestionInstances()
{
// Here generate the unique questions to be included in test instance from list of questions in this.Exam
}
}
And then just creating an Exam Instance for each user when an exam is created
// Method in controller, service etc.
foreach (User user in exam.Semester.EnrolledStudents)
{
ExamInstance examInstance = new ExamInstance(exam, user);
_repository.CreateExamInstance(examInstance);
}
I can't help but feel this is not the best way to go about it. Is there any standard way to create records of an "instance" class from a "template" class (don't know how better to describe it). I tried looking at the use of design patterns but it doesn't seem to me like anything fits here.
Any help is appreciated.

Scaffolding MVC Controller - how to indicate dataValueField and dataTextField?

One of the overload methods of SelectList (from the Microsoft.AspNetCore.Mvc.Rendering namespace) is defined as:
public SelectList(IEnumerable items, string dataValueField, string dataTextField);
When I scaffold an "MVC Controller with view, using Entity Framework" and I create my CRUD pages, I may see the following method inside of my Controller:
public IActionResult Create()
{
ViewData["Continent"] = new SelectList(_context.Continent, **"ContinentID", "ContinentID"**);
ViewData["Country"] = new SelectList(_context.Country, **"CountryID", "CountryName"**);
return View();
}
The field supplied to the dataTextField parameter is different between Continent/Country. How does MVC/EntityFramework decide which field to supply to dataTextField when scaffolding a Controller? Is there something in the individual models or in the DbContext that I am overlooking? I'd like for the dataTextField of Continent to be "ContinentName" so that I don't have to change it manually in the future when I need to delete and then re-scaffold the Controller.
Edit:
Here are the model definitions:
The Model of the Controller that I posted above:
using System;
using System.Collections.Generic;
namespace Project.Models
{
public partial class ProjectForm
{
public int ProjectFormID { get; set; }
public int ContinentID { get; set; }
public int CountryID { get; set; }
public virtual Continent ContinentNavigation { get; set; }
public virtual Country CountryNavigation { get; set; }
}
}
The one that displays the "CountryName" in the dataTextField the way that I want to see it:
namespace Project.Models
{
public partial class Country
{
public int CountryID { get; set; }
public string CountryName { get; set; }
public virtual ICollection<ProjectForm> ProjectForm { get; set; }
}
}
The one that displays the "ContinentID" in the dataTextField the way that I do NOT want to see it:
namespace Project.Models
{
public partial class Continent
{
public int ContinentID { get; set; }
public string ContinentName { get; set; }
public virtual ICollection<ProjectForm> ProjectForm { get; set; }
}
}
There is nothing obviously different to me in the model definitions unfortunately.
I stumbled across this post today (a bit late), but see it still hasn't been answered.
While I can't say why the scaffolding chose to use one field over another in your scenarios (unless you initially had your class/model written differently the last time you cleaned/built your project), I can say how to force it to use a specific column.
Add the DisplayColumn attribute to your class. You will need to rebuild before scaffolding again for the change to take.
namespace Project.Models
{
[DisplayColumn("ContinentName")]
public partial class Continent
{
public int ContinentID { get; set; }
public string ContinentName { get; set; }
public virtual ICollection<ProjectForm> ProjectForm { get; set; }
}
}

OData v4 Expanding Multiple One-Many

I'm creating an ASP.NET Core 3.1 Web API using OData v4.
I just made a GitHub repo here containing the entire solution, even the database project with dummy data.
Some blogs helped me along the way:
Experimenting with OData in ASP.NET Core 3.1
Supercharging ASP.NET Core API with OData
I've successfully created 3 basic endpoints that can be queried (Countries, Cities and Customers).
The Country and City endpoints work as expected, it is the Customer endpoint that causes some issues on $expand.
The Customer model looks like this (please note that I am currently using domain entities instead of DTO's because I want to get everything working smoothly first, before projecting them to DTO's):
public abstract class AppEntity : IAppEntity
{
[Key]
public int Id { get; set; }
}
public class Customer : AppEntity
{
public string Name { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public virtual City City { get; set; }
public string VAT { get; set; }
public virtual List<CustomerEmailAddress> EmailAddresses { get; set; }
public virtual List<CustomerNote> Notes { get; set; }
}
With the following models acting as navigation properties:
public class CustomerEmailAddress : AppEntity
{
public Customer Customer { get; set; }
public string EmailAddress { get; set; }
public bool IsPrimary { get; set; }
}
public class CustomerNote : AppEntity
{
public Customer Customer { get; set; }
public DateTime DateTime { get; set; }
public string Message { get; set; }
}
Most of my queries are successful:
Just the collection: https://localhost:44309/api/customer
Expanding the City: https://localhost:44309/api/customer?$expand=City
On of the one-many relationships: https://localhost:44309/api/customer?$expand=Notes
But as soon as I try to expand 2 or more one-many properties or expand all (?$expand=*), I get an exception:
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
Any clue where this exception might be coming from?
My EdmModel is defined as:
IEdmModel GetEdmModel()
{
var odataBuilder = new ODataConventionModelBuilder();
odataBuilder.EntitySet<Country>("Country");
odataBuilder.EntitySet<City>("City");
odataBuilder.EntitySet<Customer>("Customer");
return odataBuilder.GetEdmModel();
}

MVC5 Models outside of area EF6

I am trying to call a public virtual into a Asset.cs to link data on the ModelID.
My issue is that the Model.cs is outside of the area of where the asset.cs is.
How do i link the two tables models together when they are separated by areas ?
Assets.cs in a area, using "model" is an issue in the public virtual because it cant find it in the Area.
namespace Assets.Areas.Company.Models
{
public class Asset
{
[Key]
public int AssetID { get; set; }
public int ModelID { get; set; }
public virtual Model ModelName { get; set; }
Model.cs outside the area
namespace Assets.Models
{
public class Model
{
[Key]
public int ModelID { get; set; }
public int AssetAssignmentID { get; set; }
[Required]
[StringLength(100, MinimumLength = 2)]
public string ModelName { get; set; }
I have tried a viewmodel approach but it just adds the fields to the asset table rather than foreign keys when i use public virtual ModelVM ModelName { get; set; }
I have tried using the using Assets.Models; to link to the model.cs when looking at public virtual Model ModelName { get; set; } , but when updating the table an object named 'models' is already in the database.
I have found i can you models outside of an area, with:
using Assets.Models;
My EF Migration was causing me the issue with "object named 'models' is already in the database." This was because the table Models was already there!

Entity Framework 5 code first not mapping a model

I have been working with EF5 trying to build an application and have run into a small problem.
I have created a model like
public class TargetBusinessModel
{
public int Id { get; set; }
public Guid BusinessId {get; set; }
public Business Business { get; set; }
public string ContactName { get; set; }
public string ContactTitle { get; set; }
public string ContactPhone { get; set; }
}
Updated the Context file
public DbSet<TargetBusinessModel> TargetBusinessModels { get; set; }
My problem is none of the properties from Business are mapped within the database.
The Business Model I am trying to add is from another project, I am not sure if that's the reason.
I don't mind if the code first creates a separate table for my Business model or combines them together.
Can anyone help out?
Try to add DbSet for Business entities to your DbContext implementation:
public DbSet<Business> Businesses { get; set; }