2017-09-15 1 views
0

Je rencontre des problèmes dans la cartographie d'un type complexe sur une classe modèle (appelé Assignment) à l'aide EntityFramework 6.code EF6 Première/erreur lancer API Courant avec des types complexes

J'ai la classe modèle Assignment suivant (seulement pertinente membres sont représentés):

public class Assignment 
{ 
    private AssignmentDueByInfo _dueIn; 

    public Assignment() { 
     _dueIn = new AssignmentDueByInfo(this) 
    } 

    public virtual AssignmentSettingInfo DueIn 
    { 
     get { return _dueIn; } 
     protected set { _dueIn = value; } 
    } 
} 

AssignmentSettingInfo est défini comme:

public class AssignmentSettingInfo 
{ 
     protected AssignmentSettingInfo(Assignment assignment) 
     { 
      Assignment = assignment; 
     } 

     protected readonly Assignment Assignment; 

     public virtual int? LessonId { get; protected set; } 
     public virtual Lesson Lesson { get; protected set; } 
} 

Dans Entity Framework 6, I ha ve les éléments suivants cartographie CodeFirst/API Fluent pour la classe Assignment à une table dans une base de données:

Property(t => t.DueIn.LessonId).HasColumnName("DueByLessonId"); 

HasOptional(x => x.DueIn.Lesson) 
      .WithMany(x => x.AssignmentsDue) 
      .HasForeignKey(x => x.DueIn.LessonId) 
      .WillCascadeOnDelete(true); 

La mise en correspondance jette l'erreur suivante:

The expression 'x => x.DueIn.Lesson' is not a valid property expression. The expression should represent a property: C#: 't => t.MyProperty'

Pourquoi cela se produit et comment faut-il fixé?

+0

Je pense c'est la limitation EF - les types complexes ne peuvent pas contenir de propriétés de navigation. –

Répondre

0

Vérifiez la documentation (il est assez vieux, mais est toujours vrai):

https://msdn.microsoft.com/en-us/library/bb738472(v=vs.100).aspx

Cela indique que les types complexes ne peuvent pas contenir des propriétés de navigation. Je suppose que cela a à voir avec le fait qu'ils n'ont pas de clés primaires et qu'ils ne sont pas gérés séparément par le contexte. Si elles n'ont pas de PK et ne peuvent pas être identifiées par le contexte, elles ne peuvent pas non plus être des «fins de relation».

0

Vous essayez de rendre l'objet SQL orienté. Les classes que vous définissez et qui représentent une table de base de données doivent être des POCO: des classes assez simples avec seulement des propriétés get et set.

Vous faites trop avec les champs. Si vous devez remplir un champ dans l'une des classes de la table, détrompez-vous. Je n'ai jamais vu un exemple où la classe qui représente une table de base de données avait besoin d'un champ, autre qu'une simple propriété get/set.

Si l'une des classes se rapporte à une autre classe, elle est effectuée par clé étrangère et non par this.

La classe Assignment représente une table de base de données. Cette table est censée avoir certaines colonnes et relations avec d'autres tables utilisant des clés étrangères. La classe Assignment ne doit pas contenir de composants intelligents ne faisant pas partie de la table.

par exemple je vois que Assignment a un champ nommé _dueIn de type AssignmentDueByInfo. Les étrangers peuvent accéder à ce champ, mais pour eux ce champ n'est pas un AssignmentDueByInfo, mais un AssignmentSettingInfo. Déterminez vous-même quelles colonnes le Assignment devrait avoir.

Y a-t-il une raison de placer les colonnes d'un AssignmentSettingInfo dans une table différente? Si je regarde votre code, il ne peut y avoir un AssignmentSettingInfo sans 'Affectation and there can't be an Affectation without an AssignmentSettingInfo`. Alors pourquoi les mettre dans des tables séparées?

Un autre problème est la relation entre AssignmentSettingInfo et Lesson. Est-ce un zéro ou un à un? Follow these guide lines

Si vous mettriez « affectation and AssignmentSettingInfo` dans une table de votre code serait comme

class Assignment 
{ 
    public int Id {get; set;} 

    // every assignment has exactly one AssignmentSettingInfo 
    // use aggregation (in entity framework terms: complextype) 
    public AssignmentSettingInfo AssignmentSettingInfo {get; set;} 
} 

[ComplexType] 
class AssignmentSettingInfo 
{ 
    // Every AssignmentSettingInfo has zero or one Lesson 
    public virtual Lesson Lesson { get; set; } 
} 

classe Leçon { public int Id {get; ensemble;}

Je ne pouvais pas
// relation between Line and AssignmentSettingInfo 
    ... 
} 

la relation entre Line et AssignmentSettingInfo. Visite:

Si vous voulez vraiment le AssignmentSettingInfo dans une autre table, le configurer comme un à une méthode comme indiqué dans les liens

+0

La raison de la division de l'attribut AssignmentSettingInfo est que la fonctionnalité de cette classe est plus qu'indiquée et qu'elle est réutilisée ailleurs. Je privilégiais la composition par rapport à l'héritage. Beaucoup a été retiré des classes ci-dessus; les champs sont là pour une raison mais en dehors de la portée de la question. – Graham