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.
Related
I'm using the database-first approach while setting my first steps in Entity Framework. In my SQL Server database I have two tables, Location and Area.
Both have an Id column and the Location table already has an AreadId property. I would like to use this property for creating a one-to-many association between both tables (many Location entries for one Area entry), so I have created the following in my EDMX diagram using the EDMX-designer:
In the automatically generated Location.cs file, it looks as follows:
public partial class Location
{
...
public int AreaId { get; set; }
...
public virtual Area Area { get; set; }
}
I would like to use the already existing property Location.AreaId as the foreign key. How can I do that, using EDMX-designer?
Please keep in mind that I can modify the EDMX diagram, but not the automatically generated Location.cs file.
Thanks in advance
I am using code first approach for my .net core project. We are using multiple schemas in single database.
We are maintaining models in different class library projects like Inventory,Sales,Finance etc ..
Model mapping is like ( note : below they are different name spaces)
[Table(name: "Product", Schema = "Inventory")]
public class Product
{
public int ProductId {get;set;}
public string Name {get;set;}
}
[Table(name: "Order", Schema = "Sales")]
public class Order
{
public int OrderId{get;set;}
public int ProductId {get;set;}
public virtual Product Product {get;set;}
}
With in the schema i am able to add relation by using attribute. Now i want to add relation between these tables.
I have tried some tweaks but not working.
Any help is appreciated.
Update:
DBcontext's also different for each schema and they are placed in respective class library
You have conflicting approaches in your current architecture:
On one hand, you have gone for a micro-services approach where each service is dealing with its own bounded context (e.g. Inventory, Sales, etc.). This seems to be confirmed by your use of different database schemas, which can be viewed as logically different databases that happen to be deployed in a single physical database. This is fine, and allows for future scaling / segregation where you might move the inventory data into its own database, for example.
On the other hand, you are trying to treat the datastore as a monolithic artefact where you can build table relationships across the bounded context boundary established by your micro-service approach.
If you wish to maintain your micro-services approach, which is perfectly reasonable, then you have to accept that you cannot rely on database-enforced referential integrity for table relationships that span entities in different micro-services.
You'd need a layer above that can retrieve data from separate micro-services and put them together into entities (preferably DTO entities, not the EF Data Entities used for code-first) that the consumer is looking for.
This layer would first retrieve Orders from the 'Sales' service, and then enumerate your Orders and retrieve the relevant Products from the 'Inventory' service and then map those into DTO entities that include navigation properties between OrderDTO and ProductDTO.
Your Order data entity should not have a virtual navigation property to "Product" but instead just hold a unique id of the Product that the Order relates to (not enforced as a database relationship). Personally, I would go further and introduce a GUID Unique Identifier to the Product data class that can be used in the Order to uniquely identify the product. That way, if you ever do migrate your Inventory tables to a new database, you don't have to worry about managing the Database Identity Column during that migration as the reference 'outside' of the Inventory service to the Product table would be the GUID Unique Identifier.
You have a typo
public virtal Product Product {get;set;}
should be virtual
Also you need a navigation member in Product
[Table(name: "Product", Schema = "Inventory")]
public class Product
{
public int ProductId {get;set;}
public string Name {get;set;}
public virtual ICollection<Order> Orders { get; set; }
}
[Table(name: "Order", Schema = "Sales")]
public class Order
{
public int OrderId{get;set;}
public int ProductId {get;set;}
public virtual Product Product {get;set;}
}
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.
This question already has answers here:
Using DataAnnotations with Entity Framework
(2 answers)
Closed 6 years ago.
I am using EF6 in a database first context. In this case I am using the entity classes in my MVC web project and would like to annotate the entity's fields with various validation and display attributes. However, when I refresh the entity classes by doing an update from database in my edmx designer, the classes regenerate and my attributes are lost.
What is the best approach to getting round this?
When working with generated entity classes in a database first Entity Framework project, it is often necessary to apply attributes to the class’s fields. This is especially the case if you are foregoing the use of ViewModels and using your entities directly in an MVC web project.
Of course if you were to apply validation or display name attributes to the fields directly, the next time the data model is generated due to an upgrade from database action, these would all be overwritten.
Luckily the classes generated by Entity Framework are marked as partial. This means that we can create a second class that augments the first. Effectively the two classes are seen as one. For example:
[MetadataType(typeof(AnimalMetaData))]
public partial class Animal
{
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int NumberOfLegs { get; set; } etc..
public class AnimalMetaData
{
[MaxLength(200)]
[Required]
public string Name { get; set; }
[MaxLength(1000)]
public string Description { get; set; } etc...
But of course we have a problem here. We have put the attribute to associate the metadata class on the entity class and this will be overwritten on an update from the database. So how do we get round this? Simple! We create a third ‘dummy’ class called Animal that sits alongside the metadata class and is also partial:
[MetadataType(typeof(AnimalMetaData))]
public partial class Animal {}
We annotate this class with our metadata class, so in effect we have the three classes acting as one; the entity itself, the dummy class to link the entity with the metadata definition class.
For the sake of keeping things tidy, you could do worse than to place the metadata and dummy classes together in a separate folder adjacent to the entities generated by Entity Framework.
I'm pretty new with ASP.NET MVC, but I know a lot more about PHP. So if I had 2 connected tables in a database, normally I'd connect them with an ID - secondary key.
Example:
Movies:
+ ID
+ Title
+ Description
+ Genre
-- Comments --
+ ID
+ MoviesID
+ Comment
Thus creating a one to many kind of relationship. But I saw that in ASP.NET MVC people would create models which would reference one another:
public class Movie {
// Annotations not included
public int ID {get;set;}
public string Title {get;set;}
public string Description {get;set;}
public string Genre {get;set;}
public List<Comment> Comment {get;set;}
}
public class Comment {
public int ID {get;set;}
public Movie Movie {get;set;}
public string Comment {get;set;}
}
So the parts where one model calls another, how does that looks like in the database, how do you fill those up in the database, how do you pass values of one comment/movie class to a database of the other class when you want to create a new row? (if that makes sense - example would be how to insert a movie object in the database for when you upload a new comment in the database.) Or if at least you could give me some source to read about it, because I found nothing.
Of course another question would be if this is smart to do, or should you just do it the "traditional" way, following the pattern I did at the top?
Hope it's understandable, thanks!
What you are referring to is an ORM what stands for Object-Relational Mapping.
Basically ORM helps you treat tables and relations between them as objects. This approach makes programming much more easier in terms of common language for code and database.
ORM tools are widely used also in PHP(search for Proper, Doctrine). For C# you can refer to NHibernate, Entity Framework or micro-ORMs like Dapper. The example you provided as a .NET approach is similar to your approach in PHP. The only difference is that you explicitely mark one property as foreign key. You could change your example to:
public class Movie {
//Annootations not included
public int ID {get;set;}
public string Title {get;set;}
public string Description {get;set;}
public string Genre {get;set;}
public List<int> CommentIds {get;set;}
}
public class Comment {
public int ID {get;set;}
public int MovieID {get;set;}
public string Comment {get;set;}
}
but this would only load identifiers for related records. When using ORM you can mark property(which in table is an identifier to the another table record) as strong-typed class, what enables you to load all its data from database.
To make long story short - when using ORM you can load whole Movie when fetching Comment from DB, not only its identifier.
Whole process and its configuration depends on ORM tool you are using, you can use mapping attributes(e.g. in Entity Framework), or fluent mappings(when using NHibernate with Fluent NHibernate). Those tools are quite complex(there are many issues to solve - eager/lazy loading, connection management, session management, LINQ to Entities and many many more, it is impossible to explain it on SO :))