I created a code first project in which there is a post model and person model:
public class post
{
[Key]
public int postId { get; set; }
public string title { get; set; }
public virtual person sender { get; set; }
}
public class person
{
[Key]
public int personId { get; set; }
public string name { get; set; }
}
I want to create a post, in which sender persons' info exists but person is defined as an object. How can I insert an existing person to a post when I create a new post? Actually I can only insert some fields like int, string etc. by taking value from views but in this case it is not a value it is an object, how can I insert the data?
e.g.
code:
ViewBag.personlist = new SelectList(db.persons,"personId","name");
view:
#Html.DropDownListFor(model => model.sender, (SelectList)ViewBag.personlist, "select item")
In database there is no sender item but person_postId, because of this reason dropdownlistfor send NULL value, how can I deal with that?
If I understand what you want correctly, you need to add the personID foreign key to your post model:
public class post
{
[Key]
public int postId { get; set; }
public int personId { get; set; }
public string title { get; set; }
public virtual person sender { get; set; }
}
As it stands you have a navigation property but no foreign key to associate the post with a person. The following line:
public virtual person sender { get; set; }
sets your navigation property, however it needs an personID from the person model to be a field in the post model so that there is a recorded link between that person and the post. Entity Framework will automatically label personID as a foreign key by virtue of having the navigation property set.
Related
I am new to MVC and this is my function. There are three tables (Order, OrderNotes, Notes), ID is their primary key. One Order can have many Notes, the table OrderNotes has foreign key OrderID(from Booking table) and NotesID(from Notes table). I want to have a Order Edit page to display individual Order (FirstName, LastName), also display a list of its Notes. Here is my DB structure:
Booking table:
{ID,
FirstName,
LastName
}
BookingNotes table:
{ID,
BookingID,
NotesID
}
Notes table:
{ID,
NoteName,
StatusID
}
So how can I implement the list of Notes since it's from multiple tables? It will be able to Create New Note, Delete existing Note in the list row record, not Edit. Linq used in DB query. Thanks.
It would be a better idea to have only 2 tables:
public class Book
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
// Navigational properties
public virtual List<Note> Notes { get; set; }
}
public class Note
{
public int ID { get; set; }
public int BookID { get; set; }
public string NoteName { get; set; }
public int StatusID { get; set; }
// Navigational properties
public virtual Book Book { get; set; }
public virtual Status Status { get; set; }
}
A third table is useful when you want to reuse the same Note for a different booking. However i think this is not the case.
So to retrieve data for your context make sure you have the DbSet<Book>
public class ApplicationDbContext : DbContext
{
public virtual DbSet<Book> Bookings { get; set; }
}
In your controller (or better in a repository class):
var BookingID = 10; // this is parameter passed to the function
var myBooking = this.dbContext.Bookings
.Include(p => p.Notes)
.ThenInclude(p => p.Status)
.FirstOrDefault(p => p.ID == BookingID);
Map the retrieved booking to a ViewModel, pass it to the View and you're good to go.
So I have two models that I am trying to get working,
public class Contract
{
[Key]
public int Id { get; set; }
public string AwardId { get; set; }
[ForeignKey("Id")]
public virtual ICollection<ContractHistory> contractHistory { get; set; }
}
And
public class ContractHistory
{
[Key]
public int Id { get; set; }
public string AwardId { get; set; }
[ForeignKey("Id")]
public virtual Contract contract { get; set; }
}
There are many ContractHistory related to one Contract.
I keep getting a run-time InvalidCastException with that setup but when I remove the navigation property within the ContractHistory, and modify the Contract navigation property to:
public virtual ContractHistory contractHistory { get; set; }
It performs the join correctly without any errors.
I only have a year of experience working with .NET and at a lose as to what the issue could be. Ideally, I would like to navigate from Contract to a list of ContractHistory and from ContractHistory to one Contract. Worst case would be for me to create independent data repository methods to explicitly pull in these records but would prefer to figure out the solution to this problem for future reference.
Any advice or follow up questions are welcomed and thanks in advance!
Your ContractHistory class does not have a foreign key property.
Furthermore, you don't need to have the ForeignKeyAttribute overtop of public virtual ICollection<ContractHistory> contractHistory { get; set; } because you should be referencing the foreign key in the ContractHistory class.
The ForeignKeyAttribute constructor takes a string as a parameter.
Per MSDN
Parameters
name
Type: System.String
If you add the ForeigKey attribute to a foreign key property, you should specify the name of the associated navigation property. If you add the ForeigKey attribute to a navigation property, you should specify the name of the associated foreign key(s). If a navigation property has multiple foreign keys, use comma to separate the list of foreign key names.
So in your case:
[ForeignKey("Id")]
public virtual Contract contract { get; set; }
You are placing the ForeignKeyAttribute on the navigation property, contract. So essentially your class will search for a property called Id and identify that as the foreign key. But in your class, Id has the Key attribute which means you are declaring that as your primary key.
So in order to resolve this, you need to add another property to your ContractHistory class that will be the foreign key. And then change the string in your ForeignKeyAttribute to the name of that property.
Example:
public class ContractHistory
{
[Key]
public int Id { get; set; }
public string AwardId { get; set; }
public int contractID {get;set;}
[ForeignKey("contractID")]
public virtual Contract contract { get; set; }
}
Hope this helps!
As far as I see you want to implement one-to-many relationship, if so you have to remove the foreginkey attribute from the contract history collection in the contract class, and add contractId property as foreignkey in the contract history class as below:
public class Contract {
[Key]
public int Id { get; set; }
public string AwardId { get; set; }
public virtual ICollection<ContractHistory> contractHistory { get; set; }
}
public class ContractHistory {
[Key]
public int Id { get; set; }
public string AwardId { get; set; }
public int ContractId { get; set;}
[ForeignKey("ContractId")]
public virtual Contract contract { get; set; }
}
I read a post from EF with MVC.The example used three tables with 1-to-many relationships. And with StudendId as the foreign key set up, I can directly call Model.Enrollments(model is of Student type ) in the view.
I'd like to know How could I set up a many-to-many relationship with two tables.
With a beginning:
public class Post
{
public int Id
{ get; set; }
public int CategoryId
{ get; set; }
public string Title
{ get; set; }
public string ShortDescription
{ get; set; }
public string Description
{ get; set; }
public virtual ICollection<Tag> Tags
{ get; set; }
}
public class Tag
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int TagId
{ get; set; }
public string Name
{ get; set; }
public string UrlSlug
{ get; set; }
public string Description
{ get; set; }
public virtual ICollection<Post> Posts
{ get; set; }
}
I'd like to call Model.Tags to get all the Tags related to a Post or call Model.Posts to get all the Posts belong to a Tag in the view. I guess I need a class something like
public class TagPost
{
public int TagId{get;set;}
public int PostId{get;set;}
}
But It looks like TagId and PostId both are foreign keys? I am not sure what to do.
Reading:
var post1 = dbContext.Post.FirstOrDefault(x => x.PostId ==1);
var tags = post1.Tags();
Inserting:
// Create a New Post Entity
var post = new Post();
// Assign it you values either from ViewModel or
post.Title ="ManyToMany";
// Create your list of tags related to Post
post.Tags = new List<Tags>();
// Add a Tag from Database to this List where TagId == 1
post.Tags.Add(dbContext.Tags.First(s => s.TagId == 1));
// save Changes
dbContext.SaveChanges();
after save Changes you will see that in you Many-to-Many Mappings table there is a new Record with
PostId = 2 // Considering you have PostId == 1 already in DB
TagId = 1 // Tag you added before dbContext.SaveChanges()
This question already has answers here:
EntityType has no key defined error
(13 answers)
Closed 6 years ago.
Developing a basic ASP.net MVC 4 application. Its a simple product catalog application, where in I have 2 database tables ('Category' and 'Products')
There is a foreign key reference of 'Category id' (primary key in Category table) in 'Products' table.
When I run the application, I am getting error message (listed below).
System.Data.Entity.Edm.EdmEntityType: : EntityType 'Category' has no key defined. Define the key for this EntityType.
System.Data.Entity.Edm.EdmEntitySet: EntityType: EntitySet 'Category' is based on type 'Category' that has no keys defined
This looks like a common error for newbies,I did check all the related solutions to 'Entity key '' has no key defined.' but still my problem is not solved, Kindly help me in understanding this problem and what is the correct solution to this problem.
Below are my model classes
Category.cs
namespace ChemicalStore.Models
{
public partial class Category
{
public int CatId { get; set; }
public string CatName { get; set; }
public string CatDescription { get; set; }
public List<Product> Product { get; set; }
}
}
Products.cs
namespace ChemicalStore.Models
{
public class Product
{
public int ProductId { get; set; }
public int CatId { get; set; }
public string ProductTitle { get; set; }
public string ProductPrice { get; set; }
public string ProductDescription { get; set; }
public string ProductPackage { get; set; }
}
}
You should add attribute [Key] before property CatId:
using System.ComponentModel.DataAnnotations;
public partial class Category
{
[Key]
public int CatId { get; set; }
public string CatName { get; set; }
public string CatDescription { get; set; }
public List<Product> Product { get; set; }
}
The problem is that EF can work only when it knows primary key of table. By default EF recognize as primary key property with name Id. If your table has another primary key, you can mark it with attribute [Key] or set Key with fluent configuration.
Entity Framework uses a primary key field to create the primary key column on the generated table.
It uses convention to get this column with some variations:
If the field is called id or any casing variance;
If the field is called ClassNameId of any casing variance;
I may be missing some more conventions, but these are the most common cases.
If you don't have any field with this conventions you need to mark your desired primary key with the attribute [Key]:
[Key]
public int CatId { get; set; }
I was able to solve this by adding a setter to my key property; I only had a getter before.
public int Id { get; set; }
Just place [key] attribute on above id ..
[Table("employee")]
public class Employee
{
[Key]
public int Empno { set; get; }
public string Empname { set; get; }
}
Entity classes are auto generated..
Manual changes to those files will be overwritten if the code is regenerated.
You need to create a partial class with all your metadata
[MetadataType(typeof(Category.CategoryMetadata))]
public partial class Category
{
internal sealed class CategoryMetadata
{
[Key]
public int CatId { get; set; }
[Required]
public string CatName { get; set; }
public string CatDescription { get; set; }
public List<Product> Product { get; set; }
}
}
Read more on MSDN
Hi if you are getting below error.
""One or more validation errors were detected during model generation:
Checking.Models.Employee: : EntityType 'Employee' has no key defined. Define the key for this EntityType.""
just check your table column name and defined property name same or not .
if not then correct it proble resolved.
In my case I fixed this problem adding the right connectionString in the web.config/app.config file.
I had forgotten adding it and the DBContext was not able to communicate with the DB.
Hope it helps
I have two models
First Model
public class Company
{
public int Id { get; set; }
public string CompanyName {get;set;}
public virtual ICollection<Member> Member { get; set; }
}
Second Model
public class Member
{
public int Id { get; set; }
public string Name { get; set; }
public virtual Company Company { get; set; }
}
So A company can have many Members
First, creating a company record and then I redirect to Member controller and when I try to save the Member record it fails.
Here is what I am doing: Id is the company id that is passed via ActionLink. Id I checked has a value. It fails when I want to assign the Id to Member's company_Id (FK)
[HttpPost]
public ActionResult Create(Member m, int id)
{
if (ModelState.IsValid)
{
**m.Company.Id = id;**
db.Member.Add(m);
db.SaveChanges();
return RedirectToAction("Index");
}
}
When the member table is created, the fields that it creates
Id, name, Company_Id(FK)
What am I doing wrong? How do I assign the companyId to Member's Company_Id (FK)?
Thanks
I think the Company is null and that is why. Do this:
public class Member
{
public int Id { get; set; }
public string Name { get; set; }
public int CompanyId Integer { get; set; }
public virtual Company Company { get; set; }
}
and in your action write:
//...
m.CompanyId = id;
//...
That should do the trick. If you want to read more about it look for navigation properties and foreign key properties.