Initialiser une Linq à l'objet Sql par la logique métier
-
22-08-2019 - |
Question
Je souhaite étendre une classe généré par LINQ to SQL pour initialiser lorsqu'un nouvel objet (= rangée) est créé.
Je veux ajouter des lignes à une table d'enfant lorsqu'une ligne parent est créé.
J'espérais utiliser la méthode Oncreated (partielle) faire quelque chose comme ceci:
partial class Product {
partial void OnCreated() {
// Fill default rows for FK relations
this.Columns.Add(new ProductColumn {
Name = "Name", ColumnType = 1
});
this.Columns.Add(new ProductColumn {
Name = "Producer", ColumnType = 2
});
}
}
Le OnCreated est appelé à chaque fois du constructeur. Donc, même si l'objet sera chargé à partir de la base de données après l'appel à OnCreated. Et si l'objet est chargé à partir de la base de données, ne veulent pas exécuter le code.
Alors, où puis-je ajouter une logique à mon modèle pour initialiser un objet (-graph)?
La solution
Je pense que vous seriez mieux dans ce cas d'utiliser une usine pour créer vos instances; Donc partout où vous avez du code actuel comme:
Product p = new Product();
Vous avez la place:
Product p = ProductFactory.CreateProduct();
Et votre méthode de CreateProduct () ressemblerait à quelque chose comme:
public Product CreateProduct()
{
var p = new Product();
p.Columns.Add(new ProductColumn {
Name = "Name", ColumnType = 1
});
p.Columns.Add(new ProductColumn {
Name = "Producer", ColumnType = 2
});
return p;
}
Autres conseils
Il n'y a pas construit dans la méthode pour elle dans le LINQ to SQL classes générées. Ils appellent onLoaded spécifiquement lorsqu'il est appelé à partir du DB, mais ils ne remettent pas rien quand ce n'est pas. Je soupçonne parce qu'il n'y a aucun moyen de savoir à coup sûr ...
Je vous recommande d'utiliser l'approche de l'usine que Chris a suggéré.
Avec LINQ to SQL, les entités sont en grande partie pas au courant du parent données contexte - seuls les membres chargés paresseux comme EntitySet<T>
connaissent ce détail. Vous pouvez identifier des jeux d'entités SENSIBLE-contexte de données en regardant .IsDeferred
(en supposant que différée) - ce sera vrai si un contexte de données est impliqué, et false sinon - mais il y a d'autres problèmes:
- LINQ to SQL attache le contexte de données (pour une exécution différée) après la constructur (et
OnCreated
) a exécuté - Si vous ajoutez des éléments manuellement dans
OnCreated
/.ctor()
, il se brise lorsque l'on tente LINQ to SQL pour fixer le contexte de données - LINQ to SQL utilise le constructeur par défaut, ce qui signifie que les médicaments génériques / etc
new()
partagera également ce code
Donc, malheureusement; non, je ne pense pas que vous pouvez le faire dans OnCreated
de quelque façon sensible. Vous pouvez:
- un second constructeur pour cet usage, qui ajoute les éléments supplémentaires
- utiliser une méthode de fabrication, à savoir une méthode de
.Create()
statique qui construit les articles correctement
(depuis LINQ to SQL n'utilisera pas non plus de ce qui précède lui-même)
Si vous utilisez le concepteur - et je présume que vous êtes parce que vous utilisez des classes partielles - vous pouvez ajouter l'association dans le concepteur et les colonnes appropriées seront ajoutés à votre objet automatiquement. MSDN a une référence sur comment créer des associations en utilisant la surface de travail de concepteur .