I have this two objects:
public class Program
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
public string Name { get; set; }
public virtual ICollection<VideoFile> Files { get; set; }
}
public class VideoFile
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
[Required]
public string Path { get; set; }
[Required]
public virtual Program Program { get; set; }
}
The two tables are correctly created in the Database, when i save the Program it insert his files childs too, but when i tried to get a program the File collection come nulls, i have LazyLoad enable, and by default entity framework return empty collection when a child collection is empty so why i have null?
Related
I created models and performed code first migration which resulted in prepopulated up down methods.
However at a later stage I added new models to my application. The new models I added were Cart, OrderDetails and Order. I then typed add-migration for each of these models which as a result produced empty up down methods.
I would like to ask why are these up down methods empty when I added a new model.
I referenced these models in the dbcontext, the same dbcontext that referenced previously created models.
These are the new model classes that I added:
public class OrderDetail
{
public int OrderDetailId { get; set; }
public int OrderId { get; set; }
public int BookId { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
public virtual Book Books { get; set; }
public virtual Order Order { get; set; }
}
public class Cart
{
[Key]
public int RecordId { get; set; }
public string CartId { get; set; }
public int BookId{ get; set; }
public int Count { get; set; }
public virtual Book Book { get; set; }
}
class Order
{
public int OrderId { get; set; }
public string Username { get; set; }
public string FirstName { get; set; }
}
Here is my dbcontext
public BookStoreOnlineDB() : base("name=BookStoreOnlineDB")
{
}
public System.Data.Entity.DbSet<BookStoreOnline.Models.Book> Books { get; set; }
public System.Data.Entity.DbSet<BookStoreOnline.Models.Author> Authors { get; set; }
public System.Data.Entity.DbSet<BookStoreOnline.Models.BookStatus> BookStatus { get; set; }
public System.Data.Entity.DbSet<BookStoreOnline.Models.Genre> Genres { get; set; }
public System.Data.Entity.DbSet<BookStoreOnline.Models.Order> Orders { get; set; }
public System.Data.Entity.DbSet<BookStoreOnline.Models.OrderDetail> OrderDetails { get; set; }
public System.Data.Entity.DbSet<BookStoreOnline.Models.Cart>Carts { get; set; }
}
In summary, how do I populate the new up down methods with regards to the newly added Cart, OrderDetail and Detail models.
N.B. The orderDetails model and cart model reference the book model(book model contains had data migration performed on it at an earlier stage and contains populated up down methods).
New to this and would really appreciate help.
Thanks
Answer:
in PM Console:
add-migration initialcreate
//this included the newly added models e.g their ids,(cart,orderdetails, order models) to the up down methods
I am using Visual Studio 2012, MVC 4, and Razor (CSHTML). I created Person.Person table in a test database. I wanted to have my model PersonModels.cs use this table so I created the following 2 classes.
public class Person
{
[Key]
public int BusinessEntityID { get; set; }
public string PersonType { get; set; }
public string Title { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Suffix { get; set; }
public int EmailPromotion { get; set; }
[XmlAttribute(DataType = "string")]
public string AdditionalContactInfo { get; set; }
[XmlAttribute(DataType = "string")]
public string Demographics { get; set; }
public string rowguid { get; set; }
public DateTime ModifiedDate { get; set; }
}
public class PersonDbContext : DbContext
{
public DbSet<Person> person { get; set; }
}
I thought that it would pick the Person.Person table since the class name was Person even though I had not included the schema. However, upon running the application and doing an insert I checked the Person.Person table but the row wasn't there. It created dbo.People table and inserted the row there! I double checked because I thought I might be drunk but I did not write People anywhere!
I read about reverse poco but I'd like to understand how this works more than making it work.
Edit: It worked! Please find the code I used attached:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
namespace client_site.Models
{
[Table("Person", Schema = "Person")]
public class TestModel
{
[Key]
public int ID { get; set; }
}
public class DefaultConnectionX : DbContext
{
public DbSet<TestModel> test { get; set; }
}
}
dbo is the default database schema. If you want to create the table in the people schema you have to add an attribute
[Table("Person", Schema = "Person")]
I am buys designing the model below:
public class LogModel
{
public class UserActivityLogs
{
[Key]
public int id { get; set; }
//Id of the user
public string userId { get; set; }
//Time of the log
public DateTime time { get; set; }
public LogActions action { get; set; }
}
// Types of actions to log
public class LogActions
{
[Key]
public int id { get; set; }
public string name { get; set; }
public string description { get; set; }
}
}
Now what I would like to know is do I need to add a table in the context for Logactions as well as UserActivityLogs or will EF see that the two tables are linked and create the log action table automatically?
Also have I specified my relationships correctly? What I was aiming for is that I can define multiple types of Logactions and then a userlog will then have a single log action associated to it.
First, don't use nested classes, it's a needless complication. Use namespaces to organize classes.
Second, don't use plural names for classes. One instance of class represents one entity. Also, use CamelCase names for properties.
Third, yes, Entity Framework will be aware of the associations between the two classes and create a database model with two tables and a foreign key.
So this leaves you with:
namespace MyApp.LogModel
{
public class UserActivityLog
{
[Key]
public int Id { get; set; }
public string UserId { get; set; }
public DateTime Time { get; set; }
public LogAction LogAction { get; set; }
}
public class LogAction
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
}
I am a MVC newbie so go easy on me please.
I am getting two errors when I try to add a migration. They are as follows:
EntityType 'Icon' has no key defined. Define the key for this EntityType.
EntityType: EntitySet 'Icons' is based on type 'Icon' that has no keys defined.
I am including the Icon inside another model, like so:
public class Icon
{
public string IconName { get; set; }
public string IconColor { get; set; }
public int BackgroundXPos { get; set; }
public int BackgroundYPos { get; set; }
public string IconColorHover { get; set; }
public int BackgroundHoverXPos { get; set; }
public int BackgroundHoverYPos { get; set; }
}
public class GalleryThumbnail : CSSBoxModel
{
[DisplayName("Thumbnail Image Outline Color")]
public string ThumbnailImageOutlineColor { get; set; }
[DisplayName("Thumbnail Menu Font")]
public CSSFont ThumbnailMenuFont { get; set; }
[DisplayName("Thumbnail Icon Color")]
public Icon ThumbnailIconColor { get; set; }
}
How is this Address class below any different which is working:
public class Address
{
public String Adress1 { get; set; }
public String Adress2 { get; set; }
public String Adress3 { get; set; }
public String City { get; set; }
public String County { get; set; }
public String State { get; set; }
public String Zip { get; set; }
public String Country { get; set; }
}
[Table("UserProfile")] //Could be PP empolyee, Subscriber or Subscriber's customer
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public bool? Gender { get; set; }
public Address Address { get; set; } //billing address
public Address ShipAddress { get; set; }
}
I did not add a key in either my Icon or Address class because I have no intention of storing specific data in my DB. They are merely to be used inside other classes. So wy is one neededing an ID and the other is not?
I have not created public DbSet Icons { get; set; } in my DB Context either.
Also can you tell me what it is called when you use a class inside another ( or instance of class inside a class as in these examples ) ?
Much appreciated!
Since the address entity has no key defined it the Entity Framework assumes it's a complex property, and your UserProfile table will be rendered with columns named Addres_Address1, Address_Address2, Address_Address3, Address_City, and so on...
Even though you haven't declared an EntitySetIcons DbSet on your context class, it's still being added implicitly because one of your other classes somewhere has an ICollection or IEnumerable property defined.
More info on Code Conventions here:
http://msdn.microsoft.com/en-us/data/jj679962.aspx
So, either decorate the collections as NotMapped like #Kamyar said or simply remove the references from any class already declared as a DbSet.
you can use [NotMapped] attribute in System.ComponentModel.DataAnnotations.Schema namespace in EntityFramework.dll:
using System.ComponentModel.DataAnnotations.Schema;
...
[NotMapped]
public Address Address { get; set; } //billing address
[NotMapped]
public Address ShipAddress { get; set; }
Regarding the naming, AFAIK these are called public properties as well.
I've created a standard MVC 4 application using the built in account controllers/models/views. I've now tried to add another controller but I want to create a foreign key relationship to an existing user, but im getting the error message:
The ForeignKeyAttribute on property 'CreatedBy' on type 'MVC4App.Models.ListingModel' is not valid. The foreign key name 'UserId' was not found on the dependent type 'MVC4App.Models.ListingModel'. The Name value should be a comma separated list of foreign key property names.
The Listing Model Code is:
using System;
using System.ComponentModel.DataAnnotations.Schema;
namespace MVC4App.Models
{
public class ListingModel
{
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Location { get; set; }
public string Instrument { get; set; }
public string Genres { get; set; }
public string Description { get; set; }
[ForeignKey("UserId")]
public virtual UserProfile CreatedBy { get; set; }
public DateTime CreatedOn { get; set; }
}
}
What am I missing here? Or is there a better way I should be doing this?
Also I'm assuming I can just add extra properties to the user profile such as an email address or a link to an avatar image later on in the project?
You have to add the UserId to your entity:
namespace MVC4App.Models
{
public class ListingModel
{
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Location { get; set; }
public string Instrument { get; set; }
public string Genres { get; set; }
public string Description { get; set; }
public int UserId {get; set;}
[ForeignKey("UserId")]
public virtual UserProfile CreatedBy { get; set; }
public DateTime CreatedOn { get; set; }
}
}