I'm trying to use the Code-First approach with EntityFramework 6.1.3. Created a model that should describe the following: File type, which can contain multiple SEPropertyValue and Path. An attempt to save changes throws an exception: Во время создания модели обнаружены ошибки проверки. Root.ProjectName.DataModel.Type: : Для EntityType "Type" не определены ключи. Определите ключ для этого EntityType. Types: EntityType: Набор EntitySet "Types" основан на типе "Type", в котором не определены ключи. Во время создания модели обнаружены ошибки проверки. Root.ProjectName.DataModel.Type: : Для EntityType "Type" не определены ключи. Определите ключ для этого EntityType. Types: EntityType: Набор EntitySet "Types" основан на типе "Type", в котором не определены ключи.

I can not "decrypt" this message, in which my type of error? Keys like all listed?

Model:

 namespace Root.ProjectName.DataModel { using System; using System.Data.Entity; using System.Linq; public class AggregatorContext : DbContext { public AggregatorContext() : base("name=AggregatorContext") { } public virtual DbSet<File> Files { get; set; } public virtual DbSet<Path> Paths { get; set; } public virtual DbSet<SEProperty> SEProperties { get; set; } public virtual DbSet<SEPropertyValue> SEPropertyValues { get; set; } } public class File { [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } [Required] public DateTimeOffset Created { get; set; } [Required] public string Path { get; set; } public File() { this.SEProperties = new HashSet<SEPropertyValue>(); this.Paths = new HashSet<Path>(); } virtual public ICollection<SEPropertyValue> SEProperties { get; set; } virtual public ICollection<Path> Paths { get; set; } } public class Path { [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } [Required] public string FullPath { get; set; } [Required] public DateTimeOffset ProcessingTime { get; set; } public Path() { this.Files = new HashSet<File>(); } public virtual ICollection<File> Files { get; set; } } public class SEProperty { [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } [Required] public string GroupName { get; set; } [Required] public int InternalId { get; set; } public string Name { get; set; } [Required] public Type Type { get; set; } public SEProperty() { this.Values = new HashSet<SEPropertyValue>(); } public virtual ICollection<SEPropertyValue> Values { get; set; } } public class SEPropertyValue { [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int Id { get; set; } public string Value { get; set; } public virtual File File { get; set; } public virtual SEProperty SEProperty { get; set; } } 
  • and where is the class Type ? this time. secondly, I do not see the [ComplexType] Annotations for the Type property in the SEProperty class. for cases of following conventions, the [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] annotation can be omitted - Bald
  • @Bald is the question. I have no such class. - XelaNimed
  • Why do you SEProperty this property in the class SEProperty ? - Bald
  • @Bald property is needed to save property type (Int, String, bool, etc.) - XelaNimed
  • Are you trying to use this Type as a field in a table? Why not create your own class that will be used to determine the type of property ? - Bald

1 answer 1

The problem is that Type is not a primitive type and it is not configured, but a class, for storing type and value I would suggest using strings .... and with 2 fields, in one define the type name, in the other value ... Or, if the value may not be a primitive type, such as class or struct, then generally use serialization ....

Just as @Bald rightly noted, you can create a separate type with the same two fields, but I think it is a bit unnecessary if both of these fields have the Required attribute, since will result in an unnecessary JOIN in the query ...