Navigation Property Issue With Entity Framework (ASP.NET MVC) - c#

My database structure looks like this: Categories table, Questions table and Answers table. Questions have a CategoryID, and Answers have an AnswerID. When trying to access the navigation property "Answers" in my view, I receive the following error:
"'System.Data.Entity.Core.EntityCommandExecutionException' occurred in
EntityFramework.SqlServer.dll but was not handled in user code" Which
is accompanied by:
"Invalid column name 'Question_ID'."
Here's what my classes look like:
public class Category
{
public int ID { get; set; }
public string Text { get; set; }
public string Description { get; set; }
public virtual List<Question> Questions { get; set; }
}
For Question:
public class Question
{
public int ID { get; set; }
public int CategoryID { get; set; }
public string Text { get; set; }
public virtual List<Answer> Answers { get; set; }
public virtual Category Category { get; set; }
}
And for Answer:
public class Answer
{
public int ID { get; set; }
public int QuestionID { get; set; }
public string Text { get; set; }
public int Correct { get; set; }
public virtual Question Question { get; set; }
}
And my Database uses exactly the same field names, with foreign keys applied. I have tried so many variations on the names, including changing the foreign keys to 'Question_ID'and 'Category_ID' but no luck. I've also tried this solution: Code First conventions confusion but it didn't work. Anybody know where I'm going wrong?

I believe the problem is with your answer class. Try this...
public class Answer
{
public int ID { get; set; }
public string Text { get; set; }
public int Correct { get; set; }
[ForeignKey("Question")]
public int QuestionID { get; set; }
public virtual Question Question { get; set; }
}

Related

Code First Entity Framework - Column returns null becuase EF changed the name to include _ID

Entity framework changed the column name in the DB, and isn't giving me it's value.
Here are my classes:
public class Settings
{
[Key]
public int ID { get; set; }
public string Setting { get; set; }
public string MoreDetail { get; set; }
public SettingTypes Type { get; set; }
public SettingGroups SettingGroup { get; set; }
public int? MinMembership { get; set; }
public string DefaultValue { get; set; }
public int? ParentID { get; set; }
public int Order { get; set; }
}
public class SettingTypes
{
[Key]
public int ID { get; set; }
[MaxLength(35)]
public string TypeName { get; set; }
}
public class SettingGroups
{
[Key]
public int ID { get; set; }
[MaxLength(35)]
public string GroupName { get; set; }
}
In the DB you can see that it changed the name of the two columns:
When I try to loop through the results, type is null:
How do I retrieve this value? I've tried renaming the columns in the class and in the DB but that just breaks more things. What's the proper way to handle this?
Thanks!
Dangit, I figured it out. Spent way to much time doing so.
It was as simple as adding "virtual" to the properties:
public virtual SettingTypes Type { get; set; }
public virtual SettingGroups SettingGroup { get; set; }
Now I can address it like:
setting.Type.TypeName
Hope this saves someone else some time.

How to define a navigation property via Entity Framework code first approach

I have the following class that I want to use as my data context in Entity Framework:
public class AggregateRecord : IAggregateRecord
{
[Key]
public int AggregateRecordID { get; set; }
public DateTime? InsertDate { get; set; } = DateTime.Now;
public DateTime BookingDate { get; set; }
public string AmountTypeName { get; set; }
public int? UnifiedInstrumentCode { get; set; }
public double? Amount { get; set; }
public string BookingAccountID { get; set; }
public string AccountCurrency { get; set; }
public string ClientCurrency { get; set; }
public string AffectsBalance { get; set; }
public string AssetType { get; set; }
public string UnderlyingInstrumentSubType { get; set; }
public string InstrumentSymbol { get; set; }
public string InstrumentSubType { get; set; }
public string UnderlyingInstrumentAssetType { get; set; }
public string UnderlyingInstrumentDescription { get; set; }
public string UnderlyingInstrumentSymbol { get; set; }
public string UnderlyingInstrumentUic { get; set; }
public double? AmountAccountCurrency { get; set; }
public string AmountClientCurrency { get; set; }
public string InstrumentDescription { get; set; }
public virtual ICollection<InstrumentInfo> InstrumentInfo { get; set; }
}
public class InstrumentInfo
{
[Key]
public int InstumentInfoID {get;set;}
public string SomeInformation { get; set; }
public int AggregateRecordID { get; set; }
public virtual AggregateRecord AggregateRecord { get; set; }
}
I have studies the examples provided for EF6 but I still have the problem that when I try to update my migration that I get the following error:
One or more validation errors were detected during model generation:
There are no primary or candidate keys in the referenced table 'dbo.AggregateRecords' that match the referencing column list in the foreign key 'FK_dbo.InstrumentInfoes_dbo.AggregateRecords_AggregateRecordID'.
Could not create constraint or index. See previous errors.
How do I have to define the classes so that InstrumentInfo can be accessed via a navigation property?
public class InstrumentInfo
{
[Key]
public int InstumentInfoID {get;set;}
public string SomeInformation { get; set; }
public int AggregateRecordId { get; set; }
public virtual AggregateRecord AggregateRecord { get; set; }
}
Seems you forgot "public"
I "solved" the problem. It's weird, but maybe it helps somebody in future that's why I answer my own question.
I renamed my class AggregateRecord to AggregateEntry. Performed the Add-Migration and Update-Database, with the new renamed class name. And it worked.
It looks like there was some problem with the migration definition or whatsoever, but it solved it.
In the end, I renamed it back to the original name, did the same procedure again and, voila, it works.
#Dennis Spade: Thanks for your effort, without your hint it would have taken me even more time to find the real "problem".

Entity Framework C# Introducing A Foreign Key X In Table Y May Cause Cycles OR Multiple Cascade Paths

I am developing a C# MVC application. I am using Code First approach to model my database.
My project had the following requirements:
Company Can Have Many Products
Product Can have many Advertisement
Types
Here are model classes (code first solution) to the above mentioned problem.
public class Company
{
public Company()
{
this.Employees = new HashSet<ApplicationUser>();
}
public int ID { get; set; }
[Required]
public string Name { get; set; }
public string Logo { get; set; }
[Display(Name="Company Description")]
public string CompanyDescription { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
public virtual ICollection<ApplicationUser> Employees { get; set; }
public virtual ICollection<Client> Clients { get; set; }
public ICollection<Product> Products { get; set; }
}
public class Product
{
public int ProductID { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
public string ProductName { get; set; }
public int CompanyID { get; set; }
public virtual Company Company { get; set; }
public virtual ICollection<AdvertisementType> AdvertisementTypes { get; set; }
}
public class AdvertisementType
{
public int AdvertisementTypeID { get; set; }
public int ProductID { get; set; }
[Display(Name = "Advertisement Name")]
public string AdvertisementTypeName { get; set; }
public DateTime Created { get; set; }
public DateTime Updated { get; set; }
public virtual Product Product { get; set; }
}
When I try to update the database, after creating the migrations i get the following error:
Introducing FOREIGN KEY constraint 'FK_dbo.AdvertisementTypes_dbo.Products_ProductID' on table 'AdvertisementTypes' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint or index. See previous errors.
I have been trying solve this problem but unable to find any solution. I don't find any problem with the model classes, nor i think there are any issues with the relationship between the models.
Any suggestions or help will be useful.
EDIT
Here is screenshot of Tables and their relations
in your dbContext you need to turn cascade delete to false if you want to avoid that.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
You can initialize your make a List() in Product like you did with Company class...
public class Product
{
public int ProductID { get; set; }
public Product()
{
this.AdvertisementTypes = new List<AdvertisementType>();
}

Invalid column name TableName_ID error

I have two tables
PropertyListing - It stores the details of the property user add, with an FK
PropertyAvailability - It's a table that stores property status ( Now Available, After 3 Months, ...)
I am trying to enforce a one-to-many relation with these two tables (Fluent API) like this
public partial class PropertyListing
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string StreetAddress { get; set; }
//the column that links with PropertyAvaibility table PK
public byte? Availability { get; set; }
public bool Status { get; set; }
public virtual PropertyAvailability PropertyAvailability { get; set; }
}
public partial class PropertyAvailability
{
public byte ID { get; set; }
public string Status { get; set; }
public virtual ICollection<PropertyListing> PropertyListings { get; set; }
public PropertyAvailability()
{
PropertyListings = new List<PropertyListing>();
}
}
I am calling this on OnModelCreating
modelBuilder.Entity<PropertyListing>()
.HasRequired(pl => pl.PropertyAvailability)
.WithMany(pa => pa.PropertyListings)
.HasForeignKey(pl => pl.Availability);
It fails with this error,
Invalid column name 'PropertyListing_ID'.
Tutorial I used: http://www.entityframeworktutorial.net/code-first/configure-one-to-many-relationship-in-code-first.aspx
What could be wrong? I know I have screwed up the naming convention EF6 expects, but isn't there a workaround?
P.S: I have seen this question asked from ef3 or so in our SO, but I am unable to find any solution and hence the question.
Add the Column attribute to you class
public partial class PropertyListing
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity), Column("ID")]
public int ID { get; set; }
public string StreetAddress { get; set; }
//the column that links with PropertyAvaibility table PK
public byte? Availability { get; set; }
public bool Status { get; set; }
public virtual PropertyAvailability PropertyAvailability { get; set; }
}

Only mapping to subset of a table

Weird question here.
I have a bad situation with a database I can't change.
[Table("PROJTABLE")]
public class Certifikat {
[Key]
public long Recid { get; set; }
public String DATAAREAID { get; set; }
public String Projid { get; set; }
public virtual StandardAndScope StandardInfo { get; set; }
}
[Table("DS_CRT_PROJSTANDARDSCOPE")]
public class StandardAndScope {
[Key]
public long RECID { get; set; }
public String DATAAREAID { get; set; }
public String Standard { get; set; }
public String Scope { get; set; }
}
I have an optional one-to-many relationship from Certifikat to StandardAndScope. However! It's only one-to-many if the DATAAREAID column is a certain value ("crt").
Do I have any way of telling EntityFramework only to map rows where the value of that column is crt?

Categories

Resources