I am trying to make changes to a database by using Entity Framework (code-first). Everything works fine up until I attempt to save changes, when an error is thrown:
Invalid Column Name BasketID
However, during debugging, looking at the storeDB.BasketItems, the basketitem was actually added.
What am I missing ?
Code:
// Basket is ENTIRELY Empty, add new item and move on.
if (storebasket == null || storebasket.BasketItems.Count == 0)
{
// Add item as is
BasketItem newItem = new BasketItem
{
sellerSKU = basketItem.sellerSKU,
BasketID = basketID,
sellerID = 1,
Quantity = basketItem.Quantity,
Price = basketItem.Price
};
storeDB.BasketItems.Add(newItem);
storeDB.SaveChanges();
}
Database entity:
public class StoreEntities : DbContext
{
public DbSet<Order> Order { get; set; }
public DbSet<OrderItems> OrderItems { get; set; }
public DbSet<Basket> Basket { get; set; }
public DbSet<BasketItem> BasketItems { get; set; }
}
Classes:
public class Basket
{
[Key]
public string BasketID { get; set; }
public virtual IList<BasketItem> BasketItems { get; set; }
public System.DateTime DateCreated { get; set; }
public Guid UserID { get; set; }
}
public class BasketItem
{
[Key]
public int BasketItemID { get; set; }
public virtual string BasketID { get; set; }
[Required]
public int sellerID { get; set; }
[Required]
public string sellerSKU { get; set; }
[Required]
public int Quantity { get; set; }
[Required]
public decimal Price { get; set; }
}
OP pasted Edit as Answer:
I have no idea why this fixed the problem, but the program works as expected now
public StoreEntities(): base("storeDBConnectionString")
{
Database.SetInitializer<StoreEntities>(
new DropCreateDatabaseAlways<StoreEntities>());
If you Look at your BasketItem class you set your BasketID as virtual... That causes entity framework not to bind the property to a column. The correct way to do it would be :
public class BasketItem
{
[Key]
public int BasketItemID { get; set; }
public virtual Basket Basket { get; set; }
public string BasketID { get; set; }
[Required]
public int sellerID { get; set; }
[Required]
public string sellerSKU { get; set; }
[Required]
public int Quantity { get; set; }
[Required]
public decimal Price { get; set; }
}
Related
It's a class where i need to add item in Subtasks with Ef Core. Have no idea how to do it. Please help!
public class Do
{
[Key]
public int Id { get; set; }
[Required]
public string Title { get; set; }
[Required]
public string Description { get; set; }
public string Executors { get; set; }
public DoStatus Status { get; set; }
public DateTime Created { get; set; } = DateTime.Now;
[Required]
public int Plan { get; set; }
public int Fact { get; set; }
public DateTime? Finished { get; set; }
public virtual ICollection<Do> SubTasks { get; set; } = new List<Do>();
}
you need to learn about the recursive CTE relationship
for the date configure there with Api
builder.Property(p => p.Created).HasDefaultValueSql("(newid())")
public class Task
{
[Key]
public int Id { get; set; }
[Required]
public string Title { get; set; }
[Required]
public string Description { get; set; }
public string Executors { get; set; }
public DoStatus Status { get; set; }
public DateTime Created { get; set; };
[Required]
public int Plan { get; set; }
public int Fact { get; set; }
public DateTime? Finished { get; set; }
public int DoId { get; set; } // id parent
public virtual List<Task> SubTasks { get; set; };
}
var id = 1 // id Do
var subTasks = db.Task.include(s => s.SubTasks).where(s => e.DoId = id).ToList()
I have this complex model:
public class Food
{
[Key]
public int FoodID { get; set; }
[Required]
[DisplayName("Food Name")]
public string FoodNameEN { get; set; }
[Required]
[DisplayName("Food Name")]
public string FoodNameFR { get; set; }
[Required]
[DisplayName("Food Name")]
public string FoodNameNL { get; set; }
[Required]
[DisplayName("Food Description")]
public string FoodDescriptionEN { get; set; }
[Required]
[DisplayName("Food Description")]
public string FoodDescriptionFR { get; set; }
[Required]
[DisplayName("Food Description")]
public string FoodDescriptionNL { get; set; }
public int CategoryID { get; set; }
[Required]
public bool Availability { get; set; }
[Required]
[DisplayName("Is Menu of the Day")]
public bool DailyMenu { get; set; }
public virtual Category Category { get; set; }
public virtual ICollection<FoodAttributeValue> FoodAttributeValues { get; set; } = new HashSet<FoodAttributeValue>();
public virtual ICollection<OrderDetail> OrderDetails { get; set; } = new HashSet<OrderDetail>();
public class Category
{
[Key]
public int CategoryID { get; set; }
[Required(ErrorMessage = "Please enter a Category Name for English")]
[DisplayName("Category Name")]
public string CategoryEN { get; set; }
[Required(ErrorMessage = "Please enter a Category Name for French")]
[DisplayName("Category Name")]
public string CategoryFR { get; set; }
[Required(ErrorMessage = "Please enter a Category Name for Dutch")]
[DisplayName("Category Name")]
public string CategoryNL { get; set; }
[Required]
public bool Availability { get; set; }
public virtual ICollection<Food> Foods { get; set; } = new HashSet<Food>();
}
public class Attribute
{
[Key]
public int AttributeID { get; set; }
public string AttributeNameEN { get; set; }
public string AttributeNameFR { get; set; }
public string AttributeNameNL { get; set; }
public virtual ICollection<AttributeValue> AttributeValues { get; set; } = new HashSet<AttributeValue>();
}
public class AttributeValue
{
[Key]
public int AttributeValueID { get; set; }
public int AttributeID { get; set; }
public string AttributeValueEN { get; set; }
public string AttributeValueFR { get; set; }
public string AttributeValueNL { get; set; }
public virtual Attribute Attribute { get; set; }
public virtual ICollection<FoodAttributeValue> FoodAttributeValues { get; set; } = new HashSet<FoodAttributeValue>();
}
public class FoodAttributeValue
{
[Key]
[Column(Order = 0), ForeignKey("Food")]
public int FoodID { get; set; }
[Key]
[Column(Order = 1), ForeignKey("AttributeValue")]
public int AttributeValueID { get; set; }
public decimal Price { get; set; }
public string CreatorUserName { get; set; }
public DateTime DateCreated { get; set; }
public virtual Food Food { get; set; }
public virtual AttributeValue AttributeValue { get; set; }
}
Attributes contains an attribute type like size or volume
AttributeValue contains the values for an attribute, like Normal Size, or Large.
FoodAttributeValue is a many to many table with payload "Price". So basically, the same Food comes in different sizes with different Prices.
My DatabaseContext:
public class ModelContext: DbContext
{
public DbSet<Category> Categories { get; set; }
public DbSet<Food> Foods { get; set; }
public DbSet<Attribute> Attributes { get; set; }
public DbSet<AttributeValue> AttributesValues { get; set; }
public DbSet<FoodAttributeValue> FoodAttributeValues { get; set; }
}
How can i query the model using linq, with the intention to have on the same view, the list of Foods that contain also the Attributes of the Food, the AttributeValues of it and eventually the Price?
Thanks in advance!
In MVC it is a best practice to create a ViewModel (or DTO) designed for the view you want to display. Generally, try to avoid using your entity POCOs in the view.
So for example:
public class FoodIndexViewModel
{
// Add the various entity fields you want here.
public int FoodID { get; set; }
...
// Take all these annotations out of your entity model. They belong here.
[Required]
[DisplayName("Food Name")]
public string FoodNameEN { get; set; }
...
[Required(ErrorMessage = "Please enter a Category Name for English")]
[DisplayName("Category Name")]
public string CategoryEN { get; set; }
public decimal Price { get; set; }
... etc. etc.
}
Now you can compose a LINQ query to populate the view model. AutoMapper can greatly ease this process.
var listOfFoodsVM = context.Foods
.Where(food => food.Availability)
.Select(food => new FoodIndexViewModel
{
FoodId = food.FoodId,
FoodNameEN = food.FoodNameEN,
... // other fields from food
CategoryEN = food.Category.CategoryEN,
// Here you would either pick a single value from the list based on your criteria
Price = food.FoodAttributeValues.FirstOrDefault(fav => fav.AttributeValueID == 1).Price
// or you could include a collection of FoodAttributes in your viewmodel:
FoodAtributes = food.FoodAttributes
... etc.
}).ToList();
Now you pass this into your view.
return View(listOfFoodsVM );
I have following model classes
Each Item has 4 languages in perticular languages table
public class Item
{
[Key]
public int Id { get; set; }
public DateTime? ExpireDate { get; set; }
}
public class ItemLanguage
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey("Language")]
public int LanguageId { get; set; }
[ForeignKey("Item")]
public int ItemId { get; set; }
public Language Language { get; set; }
public Item Item { get; set; }
}
Each item library has 4 languages in perticular language table
public class ItemLibrary
{
[Key]
public int Id { get; set; }
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd MMM yyyy}")]
public DateTime? ExpireDate { get; set; }
}
public class ItemLibraryLanguage
{
[Key]
public int Id { get; set; }
[Required]
public string Name { get; set; }
[ForeignKey("Language")]
public int LanguageId { get; set; }
[ForeignKey("ItemLibrary")]
public int ItemLibraryId { get; set; }
public ItemLibrary ItemLibrary { get; set; }
public Language Language { get; set; }
}
Now I want to add items to the ItemLibraryItems table.
It need to save the ItemId and the ItemLibraryId in this table(Not the languageId). When displaying the selected items for the library it needs to show the according to the selected language in login.
public class ItemLibraryItem
{
[Key]
public int Id { get; set; }
[ForeignKey("ItemLibrary")]
public int ItemLibraryId { get; set; }
[ForeignKey("Item")]
public int ItemId { get; set; }
public ItemLibrary ItemLibrary { get; set; }
public Item Item { get; set; }
}
But when I'm trying to create the Controller by using ItemLibraryItem as the model class it gives the error
The entity types 'ItemLibraryItem' and 'ItemLibraryLanguage' cannot share table 'ItemLibraryLanguages' because they are not in the same type hierarchy or do not have a valid one to one foreign key relationship with matching primary keys between them.
DB relationship:
1ApplicationUser : n Tickets
1ApplicationUser: n Activities
1Tickets:n Activites
I would like to design above database using code first. However,there's error warning
"Column name 'ApplicationUserId' in table 'Tickets' is specified more
than once."
However, I checked there's only one ApplicationUserId in Table Ticket as shown in below class.
Would anyone please help how to fix it? Thanks.
The entity class are as following:
Ticket Class
public class Ticket
{
public int ID { get; set; }
public Ticket()
{ TicketCreateDate = DateTime.Now; }
public DateTime TicketCreateDate { get; set; }
public int TicketCreateBy { get; set; }
public DateTime TicketCloseDate { get; set; }
public int TicketCloseBy { get; set; }
public DateTime LastTicketUpdateDate { get; set; }
public int LastUpdateBy { get; set; }//Ticket Last Update by
public DateTime TicketAssignedDate { get; set; }
public int TicketAssignedTo { get; set; }
public string TicketType { get; set; }
public string Priority { get; set; }// Ticket priority
public string TicketStatus { get; set; }
public string TicketDescription { get; set; }
public int DeviceUserID { get; set; }
public string DeviceBrand { get; set; }
public string DeviceType { get; set; }
public virtual ICollection<Activity> Activities { get; set; }
public int ApplicationUserID { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
}
Acitivity Class
public class Activity
{
public int ID { get; set; }
public Activity()
{
CreatedTime = DateTime.Now;
}
public DateTime CreatedTime { get; set; }
public string ActivityDetails { get; set; }
public int ApplicationUserID { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
public int TicketId { get; set; }
public virtual Ticket Ticket { get; set; }
}
ApplicationUser Class
public class ApplicationUser : IdentityUser
{
public virtual ICollection<Ticket> Tickets { get; set; }
public virtual ICollection<Activity> Activities { get; set; }
}
I have three simple classes and I am wiring up EF6 to an existing database.
Classes are as follows
namespace Infrastructure.Models
{
[Table("Applications")]
public class Application
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid ApplicationID { get; set; }
public DateTime DateTime { get; set; }
public string CompletedZipFileURL { get; set; }
public virtual BusinessInfo BusinessInfo { get; set; }
public Application()
{
this.ApplicationID = Guid.NewGuid();
this.DateTime = DateTime.Now;
this.CompletedZipFileURL = string.Empty;
this.BusinessInfo = new BusinessInfo();
this.BusinessInfo.ApplicationID = this.ApplicationID;
}
}
[Table("BusinessInfo")]
public class BusinessInfo
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid BusinessID { get; set; }
public Guid ApplicationID { get; set; }
public string BusinessName { get; set; }
public string BusinessType { get; set; }
public string StreetAddress { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string BusinessTelephone { get; set; }
public string FEIN { get; set; }
public string ILSalesTaxNo { get; set; }
public string IncorporateDate { get; set; }
public virtual ApplicantInfo ApplicantInfo {get;set;}
public BusinessInfo()
{
this.BusinessID = Guid.NewGuid();
this.ApplicantInfo = new ApplicantInfo();
this.ApplicantInfo.BusinessID = this.BusinessID;
}
}
public class ApplicantInfo
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid ApplicantID { get; set; }
public Guid BusinessID { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public string HomeAddress { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
public string EmailAddress { get; set; }
public string PhoneNo { get; set; }
public string Criminal { get; set; }
public ApplicantInfo()
{
this.ApplicantID = Guid.NewGuid();
}
}
}
My Context Class looks like the following:
public class SIDEntities : DbContext
{
public SIDEntities() : base(Settings.GetSetting("ConnectionString"))
{
base.Configuration.ProxyCreationEnabled = false;
base.Configuration.LazyLoadingEnabled = false;
}
public virtual DbSet<Infrastructure.Models.Application> Application { get; set; }
public virtual DbSet<Infrastructure.Models.BusinessInfo> BusinessInfo { get; set; }
public virtual DbSet<Infrastructure.Models.ApplicantInfo> ApplicantInfo { get; set; }
}
On my existing database, I have the following table names and fields:
Applications (ApplicationID : uniqueidentifier, DateTime : datetime, CompletedZipFileURL : varchar(500))
BusinessInfo (BusinessID : uniqueidentifier, ApplicationID : uniqueidentifier,...)
ApplicationInfo (ApplicantID : uniqueidentifier, BusinessID : uniqueidentifier, ...)
For some reason, as soon as I attempt to do a query against the root Application POCO, I am receiving an error to the effect of "{"Invalid column name 'BusinessInfo_BusinessID'."}".
I have attempted to debug this issue checking out various SO posts but the examples/fixes don't apply to my database first scenario.
The query that is throwing the exception is:
public static Infrastructure.Models.Application Find(Guid id)
{
using (SIDEntities cntx = new SIDEntities())
{
Infrastructure.Models.Application x = new Infrastructure.Models.Application();
//the line below is where the error occurs
x = cntx.Application.Where(m => m.ApplicationID == id).SingleOrDefault();
return x;
}
}
I can see while debugging that the query being generated from LINQ is as follows
SELECT 1 AS [C1],
[Extent1].[ApplicationID] AS [ApplicationID],
[Extent1].[DateTime] AS [DateTime],
[Extent1].[CompletedZipFileURL] AS [CompletedZipFileURL],
[Extent1].[BusinessInfo_BusinessID] AS [BusinessInfo_BusinessID]
FROM [dbo].[Applications] AS [Extent1]
I understand WHY I am getting the error back and that is because there is no "BusinessInfo_BusinessID" column in the Applications table.
I would greatly appreciate any help/pointers that I could get on this one.
Check this out
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Guid BusinessID { get; set; }
In your query, change Where and SingleOrDefault to:
x = cntx.Application.SingleOrDefault(m => m.ApplicationID == id);
Hope it helps
I have discovered that because I had a one-to-one relationship (that doesn't technically exist on the SQL server, I had to add a foreign key annotation underneath the [Key] property as noted:
Entity Framework 6: one-to-one relationship with inheritance
and
http://www.entityframeworktutorial.net/entity-relationships.aspx