I am using the Repository pattern with.NETCORE and am trying to return data back from an HttpGet request. The data I want back is from multiple un-related tables in SQL. I am trying to wrap my head around being able to retrieve the data from each respective repository and return an object with all data. I hope this makes sense, I am stuck and started to go down "Unit of Work" but can't find a good example that does what I would like, query multiples in un-related tables from one get request. Thanks in advance.
Step 1. Create model classes (domain model layer) for each table / view or the dataset that comes from the SQL database. Shown below:
public class DataFromTable1
{
// properties mapped with the sql table columns
}
public class DataFromTable2
{
// properties mapped with the sql table columns
}
public class DataFromTable3
{
// properties mapped with the sql table columns
}
Step 2. Write data access classes that will call the SQL database (stored proc or direct SQLstatement – I don’t recommend direct table access from .net though) to populate your model classes created in step 1. You can use any repository pattern in this step.
Step 3. Create a view model class that will wrap the model classes with its properties and hydrate them by calling the data access class create in step 2. Generally view model classes are created under the MVC project.
public class MyViewModelClass
{
public DataFromTable1 DataFromTable1 { get; set; }
public DataFromTable2 DataFromTable2 { get; set; }
public DataFromTable3 DataFromTable3 { get; set; }
}
Step 4. Use this view model to display the data in the view.
Hope this helps.
Related
I am working on a project, which uses a custom ORM. Each model is a simple POCO which is populated from the database.
Now, I need to use some of these classes to create a master-detail report in Stimulsoft Reports, and I am following this guide. But instead of using ADO.NET entity model, I use our own ORM.
The problem is, at step 5 of the article, Stimulsoft does not recognize my business objects in the Child of Business Object box and shows an empty list.
I think, the problem is with the relations between my models. Here is an example of a relation in our ORM:
public class Group
{
public int Id;
// Other properties
public List<Person> People { get; set; }
}
public class Person
{
public int Id;
// Other properties
public int GroupId;
}
This is too old instruction. Try to add two DataBand with your Business Objects.
I want to have a page where the user selects from a drop down list the category, then adds a small text about that category and uploads an image where the path of that image is saved in the database rather than the whole image. I have created a table "Categories" where the admin is authorized to fill it and the user only selects from the categories list.
Here is what I have done so far:
The create categories model:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace DemoIdentity.Models
{
public class CategoriesAdmin
{
public int ID { get; set; }
[Required(AllowEmptyStrings = false)]
[Display(Name = "category name")]
public string categoryName { get; set; }
}
public class DefaultConnection:DbContext
{
public DbSet<CategoriesAdmin> categories { get; set; }
}
}
Now I want to have another table (Data) which includes (ID, Category (category name selected from table categories), News, Image_Path). This table is in the Default Connection database. The category name is the selected category name from a drop down list, and the image path is an upload image which saves the path rather than the whole image.
I am unsure of how to achieve this.
It appears that you are confusing components of ASP.NET MVC and Entity Framework.
As the Entity Framework site states:
Entity Framework (EF) is an object-relational mapper that enables .NET
developers to work with relational data using domain-specific objects.
It eliminates the need for most of the data-access code that
developers usually need to write.
And the MVC site states that:
The ASP.NET MVC is an open source web application framework that
implements the model–view–controller (MVC) pattern.
The two frameworks meet through your model classes. MVC uses the model class to define the data, logic and rules of the application. In Entity Framework, your model class is mapped to tables in your database where it handles the direct reads and writes for you.
By creating your CategoriesAdmin model class and exposing it as a property in your DbContext class as such:
public class DefaultConnection:DbContext
{
public DbSet<CategoriesAdmin> categories { get; set; }
}
Entity Framework will have mapped your model class to a database table called CategoriesAdmins. If this table does not yet exist in your database, it will automatically create it for you. This approach in Entity Framework is known as Code First to a new Database.
Now since you already have a table that stores the available categories (CategoriesAdmin), you will need to create a second model class (called Data for the sake your example) which contains properties for the other bits of information that you want to store.
public class Data
{
// gets or sets the ID of this Data record.
public int ID {get;set;}
public string ImagePath {get;set;}
// other properties
...
}
Now that you have two model classes, you need to create a relationship between the two. In a SQL database this is achieved by Foreign Keys. In Entity Framework, you can achieve the same by using Navigational Properties.
So we update the Data model class as such:
public class Data
{
// gets or sets the ID of this Data record.
public int ID {get;set;}
public string ImagePath {get;set;}
// gets or sets the ID of the related CategoriesAdmin record.
public int CategoriesAdminId {get;set;}
// gets or sets the related CategoriesAdmin record. Entity Framework will
// automatically populate this property with an object for the related
// CategoriesAdmin record.
[ForeignKey("CategoriesAdminId")]
public virtual CategoriesAdmin CategoriesAdmin {get;set;}
// other properties
...
}
The ForeignKeyAttribute on the CategoriesAdmin property is there to give Entity Framework a further hint of the foreign key column to load the navigational property from.
Finally to be able to use your new Data model class with Entity Framework, you need to add another property to your DbContext class so that you have a means of accessing your data:
public class DefaultConnection:DbContext
{
public DbSet<CategoriesAdmin> Categories { get; set; }
public DbSet<Data> Data { get; set; }
}
Now that you have created your model classes and wired them into Entity Framework, you will now be able to use them in MVC. If you load your Data model into your view (using DefaultConnection.Data), you will be able to access the related CategoriesAdmin record by accessing the CategoriesAdmin property on the Data object.
In short: two tables means you need two models. Both models can be loaded into the single view.
Footnote: Apologies if there are large gaps in my answer as there is a lot to explain that have already been explained in other places far better than what I can. The references I have linked should hopefully fill in the gaps.
Should you need more help, please see all of the tutorials on the ASP.NET MVC website on working with data. They're much better written than my concise attempt. I would recommend following them exactly and getting the examples to work before completing your own project so that you have a better understanding of how the two frameworks work and interact with each other.
I am writing an application in MVC2 using Entity Framework
As I know ViewModel has to contain only data without any logic to database. Suppose I have Product class that is ADO.NET entity that has EntityCollection<ProductToStatus> when ProductToStatus is many-to-many table. I have ProductModel (that takes Product in its .ctor) which is passed to View.
public class ProductModel
{
....
public Product Item {get; private set;}
...
public ProductModel(Product item)
{
...
this.Item = item;
...
}
}
In View I need to render all statuses of the product, so to do it I need to query the DB by item.ProductToStatus.Select(s=>s.ProductStatus).ToList(); in the ProductModel, but this sends request to the DB and thus does it violates the MVC principle?
Is this OK or I need to do something?
you shouldn't do this. Your controller should collect the data required for your view and should package it up and pass it to the view for it to render.
So your ProductModel should either take the details of the Product it needs in its constructor or through properties (my preference) or should, at a push, use the Product it is given to do all the querying in the constructor to set all of its internal fields but not keep a reference to the Product around. I don't like the using the Product in the constructor particularly as its doing work in the constructor which is not great, but depending on what it is doing exactly it might be ok.
Its probably better to make your ProductModel have a load of properties, then you can create it like so:
var model = new ProductModel()
{
Statuses=product.ProductToStatus.Select(s=>s.ProductStatus).ToList(),
Name=product.Name,
OtherProperty=GetPropertyValue(product),
//etc
}
Yes its violating the pattern. You should fill your ViewModel in the Controller and then pass it to your view.
Off course it will work, but thats not the idea of model-view-controller.
I have created a repository that is returning data from my database using Entity Framework and I need to provide this data to my view, but before I do that I need to convert those objects into my domain model.
My schema looks like this:
TABLE Project
Id INT PRIMARY KEY
Name NVARCHAR(100)
TABLE Resource
Id INT PRIMARY KEY
FirstName NVARCHAR(100)
LastName NVARCHAR(100)
TABLE ProjectResources
Project_Id INT PRIMARY KEY -- links to the Project table
Resource_Id INT PRIMARY KEY -- links to the Resource table
I generated an entity model which ended up looking like this:
Project
|
---->ProjectResources
|
---->Resource
I have a repository that returns a Project:
public interface IProjectRepository
{
Project GetProject(int id);
}
And a controller action:
public ActionResult Edit(int id)
{
Project project = projectRepository.GetProject(id);
return View(project);
}
This doesn't seem to work very well when I try and POST this data. I was getting an EntityCollection already initialized error when it was trying to reconstruct the ProjectResources collection.
I think it is smarter to create a domain model that is a little simpler:
public class ProjectEdit
{
public string ProjectName { get; set; }
public List<ProjectResource> Resources { get; set; }
}
public class ProjectResource
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
This seems to be a little nicer since I also don't have the intermediate ProjectResources -> Resource jump. The ProjectResource would have the fields I need. Instead of doing something like:
#foreach( var resource in Model.ProjectResources ) {
#Html.DisplayFor(m => m.Resource.FirstName)
}
I can do:
#foreach( var resoure in Model.Resources ) {
#Html.DisplayFor(m => resource.FirstName);
}
My question is as follows
Should I be returning my domain model from my repository or should that be handled by the controller or some other class in the middle? If it's handled in the controller by something that maps my Project to a ProjectEdit, what would that look like?
My own view is that you shouldn't return anything to your controller or a view that is dependant on the implementation of your repository.
If you're using EF with the POCO Generator, it's reasonable to use those classes for your domain model because they're independent of the EF implementation (you could replace EF and retain the POCO's).
But if you're using EF with its EntityObjects, I believe you should convert to your domain model. If your Data Access was encapsulated in a WCF service which used a repository pattern internally, I wouldn't worry so much about returning EntityObjects from the Repository. But if you're using a Repository directly from MVC, use the Domain Model as the interface to the Repository.
We tend to always use a ViewModel as "the class in the middle" and map to and from the actual Model using...
Automapper
...or...
ValueInjecter
Your ViewModel can then be fairly independent of your Model in terms of structure if you want it to be.
What you describe is exactly what I've been doing for years, tying to follow n-tier application design.
Because you data will not always be organized the same way as your domain. What makes since in SQL is not always the same in your domain, as you've come across here.
Typically my domain knows what the repository looks like and has methods for converting to and from. My UI/views know what the domain looks like and have methods for retrieving that data (that goes in the controller).
So short answer, I would say, something in the middle (your business layer) and have that expose methods usable by your controllers to receive that data.
Okay, so i've studied c# and asp.net long enough and would like to know how all these custom classes i created relate to the database. for example.
i have a class call Employee
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
}
and i have a database with the following 4 fields:
ID
Name
EmailAddress
PhoneNumber
it seems like the custom class is my database. and in asp.net i can simple run the LINQ to SQL command on my database and get the whole schema of my class without typing out a custom class with getter and setter.
so let's just say that now i am running a query to retrieve a list of employees. I would like to know how does my application map to my Employee class to my database?
by itself, it doesn't. But add any ORM or similar, and you start to get closer. for example, LINQ-to-SQL (which I mention because it is easy to get working with Visual Studio), you typically get (given to you by the tooling) a custom "data context" class, which you use as:
using(var ctx = new MyDatabase()) {
foreach(var emp in ctx.Employees) {
....
}
}
This is generating TSQL and mapping the data to objects automatically. By default the tooling creates a separate Employee class, but you can tweak this via partial classes. This also supports inserts, data changes and deletion.
There are also tools that allow re-use of your existing domain objects; either approach can be successful - each has advantages and disadvantages.
If you only want to read data, then it is even easier; a micro-ORM such as dapper-dot-net allows you to use our type with TSQL that you write, with it handling the tedious materialisation code.
Your question is a little vague, imo. But what you are referring to is the Model of the MVC (Model-View-Controller) architecture.
What the Model , your Employee Class, manages data of the application. So it can not only get and set (save / update) your data, but it can also be used to notify of a data change. (Usually to the view).
You mentioned you where using SQL, so more then likely you could create and save an entire employee record by sending an Associative Array of the table data to save it to the database. Your setting for the Class would handle the unique SQL syntax to INSERT the data. In larger MVC Frameworks. The Model of your application inherits several other classes to handle the proper saving to different types of backends other than MS SQL.
Models will also, normally, have functions to handle finding records and updating records. This is normally by specify a search field, and it returning the record, of which would include the ID and you would normally base this back into a save / update function to make changes to record. You could also tie into this level of the Model to create revision of the data you are saving
So how the model directly correlates to your SQL structure is dependent on how you right it. Or which Framework you decide to use. I believe a common one for asp.net is the Microsoft's ASP.Net MVC
Your class cannot be directly mapped to the database without ORM tool, The ORM tool will read your configuration and will map your class to DB row as per your mappings automatically. That means you don't need to read the row and set the class fields explicitly but you have to provide mapping files and have to go through the ORM framework to load the entities, and the framework will take care of the rest
You can check nHibernate and here is getting started on nHibernate.