independent association between two non-relational / unrelated entities - entity-framework

I have a need to obtain a list of non-relational entity values using a navigational property. In the following model for FVariable, I am trying to create a navigation property for maintaining a list of VariableValue. How to define an independent association as depicted in the model of FVariable:
public virtual ICollection<VariableValue> Values { get; set; } ?
The two entities are related through VariableID and DataAttributeCollectionID properties.
Here is the FVariable Entity:
public class FVariable
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int FVariableID { get; set; }
[Index(Unique, Order = 1)]
public int VariableID { get; set; }
[ForeignKey(nameof(F.VariableID))]
public virtual Variable Variable { get; set; }
[Index(Unique, IsUnique = true, Order = 2)]
public int? DataAttributeCollectionID { get; set; }
[ForeignKey(nameof(FVariable.DataAttributeCollectionID))]
public virtual DataAttributeCollection DataAttributeCollection { get; set; }
public virtual ICollection<VariableValue> Values { get; set; }
}
Here is the VariableValue entity:
public class VariableValue
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int VariableValueID { get; set; }
[Index(Order = 1)]
public int VariableID { get; set; }
[ForeignKey(nameof(VariableValue.VariableID))]
public virtual Variable Variable { get; set; }
[Index(Order = 2)]
public double VariableValue { get; set; }
public int? DataAttributeCollectionID { get; set; }
[ForeignKey(nameof(VariableValue.DataAttributeCollectionID))]
public virtual DataAttributeCollection DataAttributeCollection { get; set; }
}

Related

Create POCO class in EF 7 code first

Say I have three tables. Settings, Facilities and FacilitySettingOverride in an existing database. The sample data:
Settings table
ID Name Value
1 test1 true
2 test2 true
Facilities table
ID Name
163 Demo1
164 Demo2
FacilitySettingOverride
FacilityId SettingId Value
163 2 False
164 1 False
164 2 False
FacilitySettingOverride has two foreign keys---FacilityId and SettingId. Also I want to make a composite key for FacilitySettingOverride.
I just don't know how to make it. My primary code.
[Table("Settings")]
public class Setting
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Value { get; set; }
public FacilitySettingOverride FacilitySettingOverride { get; set; }
}
[Table("Facilities")]
public class Facility
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<FacilitySettingOverride> FacilitySettingOverrides { get; set; }
}
[Table("FacilitySettingOverride")]
public class FacilitySettingOverride
{
[Key]
[ForeignKey("FacilityId")]
public int FacilityId { get; set; }
public string Value { get; set; }
[ForeignKey("SettingId")]
public int SettingId { get; set; }
public virtual Facility Facility { get; set; }
public virtual Setting Setting { get; set; }
I guess that it is wrong. Thanks for help.
Looking at your data and description, both Settings and Facility have one-to-many associations to FacilitySettingOverride. So Setting shouldn't have a property ...
public FacilitySettingOverride FacilitySettingOverride { get; set; }
... but a collection of FacilitySettingOverrides, just as Facility has.
This should be the proper class model:
[Table("Settings")]
public class Setting
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public string Value { get; set; }
public virtual ICollection<FacilitySettingOverride> FacilitySettingOverrides { get; set; }
}
[Table("Facilities")]
public class Facility
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<FacilitySettingOverride> FacilitySettingOverrides { get; set; }
}
[Table("FacilitySettingOverride")]
public class FacilitySettingOverride
{
[Key, Column(Order = 1)]
[ForeignKey("Facility")]
public int FacilityId { get; set; }
[Key, Column(Order = 2)]
[ForeignKey("Setting")]
public int SettingId { get; set; }
public virtual Facility Facility { get; set; }
public virtual Setting Setting { get; set; }
public string Value { get; set; }
}
The combination of KeyAttribute and ColumnAttribute ([Key, Column(Order = 1)]) is used for composite primary keys.
This is the database schema EF creates from it:

EF code first model not in sync with database

My EF Code First model for some reason is not in sync with the db. I'm getting this error:
{"Invalid column name 'Type_Id1'."}
The field is actually called 'Type_Id' so I'm not sure from where that 1 comes up. I have the table column called as Type_Id and also I've added a Type_Id in my type entity model.
Why might I be getting that error message, plus why I'm getting 1 at the end of the name?
Update
My Task class:
public class Task
{
public Task()
{
Language = 1;
Grades = new HashSet<Grade>();
Categories = new HashSet<Category>();
Subjects = new HashSet<Subject>();
Rooms = new Collection<Room>();
Tools = new Collection<Tool>();
}
[Key]
public int Id { get; set; }
public string Description { get; set; }
public virtual TaskType Type { get; set; }
public string Rules { get; set; }
[Required]
[StringLength(200), MinLength(1)]
public string Name { get; set; }
public int PreperationTime { get; set; }
public int InstructionTime { get; set; }
public int TaskTime { get; set; }
public int Type_Id { get; set; }
public string VideoLink { get; set; }
[Required]
public int Language { get; set; }
public int? MinimumParticipants { get; set; }
public int? MaximumParticipants { get; set; }
public int? Rating { get; set; }
[Required]
public string CreatedBy { get; set; }
public virtual ICollection<Grade> Grades { get; set; }
public virtual ICollection<Category> Categories { get; set; }
public virtual ICollection<Subject> Subjects { get; set; }
public virtual ICollection<Room> Rooms { get; set; }
public virtual ICollection<Tool> Tools { get; set; }
}
DBContext class:
public ApplicationDbContext() : base("DefaultConnection", false)
{
}
public DbSet<Task> Tasks { get; set; }
public DbSet<TaskType> TaskTypes { get; set; }
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
You need to add the FK attribute on your navigation property. EF is creating Type_Id1 because Type_Id already exists (although it can't tell by convention it is the FK).
[ForeignKey("Type_Id")]
public virtual TaskType Type { get; set; }
https://msdn.microsoft.com/en-us/data/jj591583.aspx#Relationships

Code first One way many to many relationship using data annotation

I have two models in my application: Stock and Report. A report can have many stocks and a stock can be used in many reports.
public enum ElectionType
{
MANAGER =1 ,
INSPECTOR ,
BOTH
}
public class Report
{
public Report()
{
Stocks = new List<Stock>();
}
public int ReportID { get; set; }
[Required]
public DateTime ShamsiDate { get; set; }
public int? StockID { get; set; }
[Required]
public ElectionType ElectionType { get; set; }
[ForeignKey("StockID")]
public virtual ICollection<Stock> Stocks { get; set;}
}
public class Stock
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int StockID { get; set; }
public int FinancialCode { get; set; }
public String NationalCode { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public String FatherName { get; set; }
public String Place { get; set; }
public int StockCount { get; set; }
public int StockPrice { get; set; }
public int StockSize { get; set; }
public int StartStock { get; set; }
public int EndStock { get; set; }
}
I want to create a one way relationship so there is no way to access a Report from a Stock. I have written this code but it doesn't work.
To do it with annotations you will need a junction table:
public class ReportStock
{
[Key, Column(Order = 1)]
public int ReportID { get; set; }
[Key, Column(Order = 2)]
public int StockID { get; set; }
[ForeignKey("ReportID")]
public virtual Report Report { get; set;}
[ForeignKey("StockID")]
public virtual Stock Stock { get; set;}
}
Then change your Report class:
public class Report
{
public Report()
{
ReportStocks = new List<ReportStock>();
}
public int ReportID { get; set; }
[Required]
public DateTime ShamsiDate { get; set; }
[Required]
public ElectionType ElectionType { get; set; }
public virtual ICollection<ReportStock> ReportStocks { get; set;}
}

EntityFramework One-To-Many fK?

BasketItem duplicateBasketItem = (from ph in storeDB.BasketItems
where ph.sellerSKU == newItem.sellerSKU
select ph).SingleOrDefault();
{"Invalid column name 'BasketID'."}
My Classes:
public class Basket
{
[Key]
public string BasketID { get; set; }
public virtual IList<BasketItem> BasketItems { get; set; }
public int? Count { 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; }
}
From the research i have done so far, the error is being cause due to relationships not being mapped properly. How would I map the relationship using modelbuilder
Each basket can(optional) contain many basketitems
Each BasketItem has a BaskedID(FK) to map back to the individual Basket.

How to use CodeFirst (EntityFramework, Microsoft) to make nullable complex column

I've got a definition like below and essentially, I want to create this in the EmailAccount class:
public EmailUser? EmailUserAccountInfo {get;set;}
the compiler gives me an error about non-nullable types. My goal is I want to make the EmailUser optional. I'm kind of confused because I can set EmailUserAccountInfo = null directly.
var r = new EmailAccount()
{
EmailUserAccountInfo = null,
Id = 1001
};
public class EmailAccount
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public EmailUser EmailUserAccountInfo { get; set; }
}
public class EmailUser
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public EmailAccount EmailAcount { get; set; }
public string EmailAddress { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string ZipCode { get; set; }
public string City { get; set; }
public string State { get; set; }
public int Temperature { get; set; }
public string WeatherString { get; set; }
public ImageDetail ImageOfUser { get; set; }
}
You can do this if you add a foreign key and you mark that nullable:
public class EmailAccount
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
// Foreign key
public int? EmailUserAccountInfoId { get; set; }
// Navigation property
public virtual EmailUser EmailUserAccountInfo { get; set; }
}
See this document about naming conventions for Code-First. (Scroll down to Relationship Convention)