Nested object null on client side in CODE FIRST EF RIA Service - entity-framework

I have nested object in EF Code First using Silverlight RIA service, I am able to get the data at service side but when I see it on client side child objects are null. Could you please guide me what's wrong.
[HasSelfValidation]
public class Batch
{
public int BatchId { get; set; }
public string BatchName { get; set; }
[Include]
[Composition]
[Association("FK_Batch_BathSetItemSet", "BatchId", "BatchSetIdItemSetId")]
public virtual ICollection<BatchSetItemSet> BatchSetItemSets { get; set; }
}
public class BatchSetItemSet
{
public int BatchSetIdItemSetId { get; set; }
public int BatchId { get; set; }
public Nullable<int> ItemSetId { get; set; }
public string CreatedBy { get; set; }
public Batch Batch { get; set; }
[Include]
[Composition]
[Association("FK_BathSetItemSet_ItemSet", "BatchSetIdItemSetId", "ItemSetId")]
public ItemSet ItemSet { get; set; }
}
public class ItemSet
{
public int ItemSetId { get; set; }
public int CustodianId { get; set; }
public string ItemSetName { get; set; }
public virtual ICollection<BatchSetItemSet> BatchSetItemSets { get; set; }
[Include]
[Composition]
[Association("FK_ItemSet_Custodian", "ItemSetId", "CustodianId")]
public virtual Custodian Custodian { get; set; }
}
and service call is : this.DbContext.Batches.Include("BatchSetItemSets.ItemSet.Custodian").Where(x => x.BatchId == batchId).SingleOrDefault();

You are close with the attributes, but they need to be changed:
[HasSelfValidation]
public class Batch
{
public int BatchId { get; set; }
public string BatchName { get; set; }
[Include]
[Composition]
[Association("FK_Batch_BathSetItemSet", "BatchId", "BatchId", IsForeignKey = false)]
public virtual ICollection<BatchSetItemSet> BatchSetItemSets { get; set; }
}
public class BatchSetItemSet
{
public int BatchSetIdItemSetId { get; set; }
public int BatchId { get; set; }
public Nullable<int> ItemSetId { get; set; }
public string CreatedBy { get; set; }
[Include]
[Association("FK_Batch_BathSetItemSet", "BatchId", "BatchId")]
public Batch Batch { get; set; }
[Include]
[Association("FK_BathSetItemSet_ItemSet", "ItemSetId", "ItemSetId")]
public ItemSet ItemSet { get; set; }
}
public class ItemSet
{
public int ItemSetId { get; set; }
public int CustodianId { get; set; }
public string ItemSetName { get; set; }
[Include]
[Composition]
[Association("FK_BathSetItemSet_ItemSet", "ItemSetId", "ItemSetId", IsForeignKey = false)]
public virtual ICollection<BatchSetItemSet> BatchSetItemSets { get; set; }
[Include]
[Association("FK_ItemSet_Custodian", "CustodianId", "CustodianId")]
public virtual Custodian Custodian { get; set; }
}
The AssociationAttribute .ctor is defined as:
AssociationAttribute(string name, string thisKey, string otherKey)
It should be configured as:
name: A unique name shared by each end of the relationship
thisKey: The name of the Property on this object that represents the key or foreign key
otherKey: The name of the Property on the other object that represents the key or foreign key
IsForeignKey: A property on AssociationAttribute to indicate if this end of the relationship is the primary key or the foreign key. It defaults to true (meaning this navigation property is a Foreign Key). By setting it to false, you indicate to WCF RIA that this object contains the Primary Key. For all AssociationAttribute usages with a given name, only one is allowed to have IsForeignKey = false. Otherwise, you will get a build error.

Related

Two tables (One To Many) And table with many have (One To Zero Or One) with the table One

Two Tables One To Many
VehicleStatus {Id , LastVehicleStatusUpdateId}
VehicleStatusUpdated {Id, VehicleStatusId, IsResponse }
I need to make (one to zero or one) to last record in VehicleStatusUpdated ...
LastVehicleStatusUpdateId ==> Navigator To VehicleStatus
like This
How can i make it with Entity Framework Annotation ??!!
public class Vehicle : IEntity<int>
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Number { get; set; }
public virtual VehicleStatus VehicleStatus { get; set; }
}
public class VehicleStatus : IEntity<int>
{
[ForeignKey("Vehicle")]
public int Id { get; set; }
public virtual Vehicle Vehicle { get; set; }
public int? LastVehicleStatusUpdateId { get; set; }
[ForeignKey("LastVehicleStatusUpdateId")]
public virtual VehicleStatusUpdate LastVehicleStatusUpdate { get; set; }
public virtual List<VehicleStatusUpdate> VehicleStatusUpdates { get; set;
}
public class VehicleStatusUpdate : IEntity<int>
{
[ForeignKey("LastVehicleStatus")]
public int Id { get; set; }
public DateTime UpdatedTime { get; set; }
public bool IsResponse { get; set; }
public int VehicleStatusId { get; set; }
[ForeignKey("VehicleStatusId")]
public virtual VehicleStatus VehicleStatus { get; set; }
}
I Tried this i got =>
Unable to determine the relationship represented by navigation property 'VehicleStatus.LastVehicleStatusUpdate' of type 'VehicleStatusUpdate'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

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

EF Data Annotation - Foreign Key - How to Customize

My issue is the following. I have a Model for an Address table as follows.
public partial class ADDRESS
{
public ADDRESS()
{
this.ADDRESS_ID = Guid.NewGuid();
}
public Guid ADDRESS_ID { get; set; }
public string ADDRESS_LINE { get; set; }
public string CITY { get; set; }
public Guid? STATE_ID { get; set; }
public string ZIP { get; set; }
}
This ADDRESS model is used throughout my application and has different validation requirements depending on where it is placed within a form.
I am wondering if there is a way to customize the data annotations. For example, the ADDRESS_LINE and CITY properties are required for OCCUPATION_ADDRESS but not required for WORK_LOCATION_ADDRESS.
public class OCCUPATION_DETAILS
{
public string COMPANY_NAME { get; set; }
public string JOB_TITLE { get; set; }
etc...
public Guid OCCUPATION_ADDRESS_ID { get; set; }
public virtual ADDRESS OCCUPATION_ADDRESS { get; set; }
public WORK_LOCATION_ID { get; set; }
public virtual ADDRESS WORK_LOCATION_ADDRESS { get; set; }
}
Or it could be that basic validation is the same (zip has to be 5 digits), but I need to adjust the "DisplayName" that is used to match the label of the form it is within.
Trying to minimize the amount of copied models I have set up; otherwise maintenance will be a nightmare.
you can achieve this by using the idea of inheritance
how?
public abstract class ADDRESS
{
public ADDRESS()
{
this.ADDRESS_ID = Guid.NewGuid();
}
public Guid ADDRESS_ID { get; set; }
public string ADDRESS_LINE { get; set; }
public string CITY { get; set; }
public Guid? STATE_ID { get; set; }
public string ZIP { get; set; }
}
public parital class OCCUPATION_ADDRESS: ADDRESS,IValidatableObject
{
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(string.IsNullOrWhiteSpace(ADDRESS_LINE))
yield return new ValidationResult("Address line is required!",new string[]{"ADDRESS_LINE"});
}
}
public parital class WORK_LOCATION_ADDRESS: ADDRESS,IValidatableObject
{
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
}
}
// and your Occupation details class will be like: instead of ADDRESS you will use the corresponding derived classes
public class OCCUPATION_DETAILS
{
public string COMPANY_NAME { get; set; }
public string JOB_TITLE { get; set; }
etc...
public Guid OCCUPATION_ADDRESS_ID { get; set; }
public virtual OCCUPATION_ADDRESS OCCUPATION_ADDRESS { get; set; }
public WORK_LOCATION_ID { get; set; }
public virtual WORK_LOCATION_ADDRESS WORK_LOCATION_ADDRESS { get; set; }
}
and the inheritance should be Table per Hierarchy (TPH)
for more information about TPH check this Table per hierarchy
hope that this will help you
regards

Operation failed: can't delete an entity from database

I have these method classes:
public class Links
{
[Key]
public int LID { get; set; }
public string Link { get; set; }
public string Type { get; set; }
public string Filename { get; set; }
public virtual int RessourceId { get; set; }
}
public class Ressource
{
[Key]
public int RessourceId { get; set; }
public string TitreR { get; set; }
public string Desc { get; set; }
//public int Position { get; set; }
public int Rating { get; set; }
public string Tags { get; set; }
public virtual int SectionId { get; set; }
public virtual int UserId { get; set; }
public virtual ICollection<Links> Links { get; set; }
}
public class Section
{
[Key]
public int SectionId { get; set; }
public string Titre { get; set; }
public virtual ICollection<Tags> Tags { get; set; }
public virtual ICollection<Ressource> Ressources { get; set; }
//public Section() { this.Tag=new List<string>(); }
}
And when I want to delete a Ressource, I have this error:
The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
error line:
_db.Entry(R).State = EntityState.Deleted;
_db.SaveChanges(); // error line
PS: It was working before I added the Filename attribute to the Links class... Any idea how to solve it? Thank you
Make foreign key nullable (i.e. change it's type from int to int?):
public virtual int? RessourceId { get; set; }
That means you can have links without resource.