Suggestion: Split out your Data Model/Entity Relationship Model away from your application's object model
In both scenarios it looks as if your data/entity model is mixed up with your application's behaviour.
From the raw data entities I see in your model, it looks as if they could be summarised as:
From a raw data/entity perspective, there seems to be no real need for separate entities to represent New or Under Review tags; In your second diagram you have various Tag entities which seem to differ only by their stored data; making those entities redundant.
Furthermore, the entities above would certainly make sense in your Data Model/Data Access Layer, but don't seem to make sense as application objects (i.e. the objects which contain behaviour/methods relating to your functional requirements - mostly those surrounding your UI/Views).
Consider typical functions for a CRUD UI application
- Read-only view for a list of partially visible data/abbreviated records
- View data including calculated fields based on a database snapshot
- Editor box to add/update new data
- Preview changes before final commit (with the option to discard)
- Validate newly typed data before enabling a button
The problem with tying your behaviour in to your entity model is that you not only make it harder to do a lot of typical CRUD UI operations, you also end up with those entity classes violating SRP.
Data Entities from a Data Model exist to represent the persistent/stored data for your application and nothing more. So - no validation, no UI/Display behaviour, no queries, no logic, just plain simple structured data.
Consider putting your complete data model (with raw data, no behaviour) into a DataModel class, which might include functions for your persistent store such as Load/Save, and accessors for the data itself.
Then using the data model for data access, you could encapsulate the rest of the application's behaviour into application objects, which are aware of your data model and it's structure, whose purpose among other things is to generate the View Data (a.k.a. "view models" to coin a popular UI term - where concerns such as UI validation might typically live; view models are application objects which are commonly used in patterns like MVC/MVP/MVVM to populate view data and to pass UI data downward to the main application).
for example:
// Possible ORM model:
class DataModel{
public List<BugReport> reports;
public List<Tag> tags;
public List<Duplicate> duplicates;
public void CreateReport(BugReport bugReport) { /* etc.. */ }
public void CreateTag(Tag tag) { /* etc.. */ }
public void Commit() { /* ... */ }
}
class BugReportMainApplication {
private DataModel model;
public BugReportMainApplication(DataModel dataModel) {
model = dataModel;
}
public BugReportListViewModel GetReportList(List<Tag> queryTags) {
// etc.
}
public EditorViewModel GetChangableReport(int id) {
// etc.
}
public void AssignTag(int bugReportId, Tag tag) {
// etc.
}
}
Raw data entities generally shouldn't be interested in interfaces/polymorphism because they have no behaviour - so the issue regarding your getDuplicate() interface method would be irrelevant to the entity model; instead handled in whichever part of your application logic which deals specifically with displaying/handling your links to duplicate BugReports.
To summarise - consider splitting your application into Layers to avoid polluting the entities representing your raw data with application-specific logic.