My ultimate aim is to have an EF model working alongside a sqlite local db. The dev is going to involve a lot of modification of the db and thus a lot of updating of the model. The gui will use a lot of Master-Detail views to edit the data.
I've figured that in order to get master-detail views working, you have to replace ICollection
and HashSet
with ObservableCollection
. I achieve this via a custom ObservableListSource
class.
I've given up on trying to achieve this via "database first." There's to many limitations/omissions on the "update model from database" option. For example, it doesn't update any changed fields or relationships, meaning you have to delete and re-impot the whole model again. You then have to change the .tt files to change Hashset and ICollection to the ObservableListSource. Overall the method just feels too shonky and hit and miss.
Thus, looked into the "Code first from Database" option. On initial tests appears a lot more robust and reliable than database first. However, it doesn't generate and .tt files, which would allow you to change all of the ICollection
entries in the generated classes.
I did find this:
Changing the generated classes from "Code First From Database" EF6
And successfully downloaded the .t4 file. I managed to get HashSet
replaced by ObservableListSource
by amending some code. Extract of the fuill entity.t4 file:
Public Sub New()
<#
foreach (var collectionProperty in collectionProperties)
{
#>
<#= code.Property(collectionProperty) #> = New ObservableListSource(Of <#= code.Type(collectionProperty.ToEndMember.GetEntityType()) #>)()
<#
}
#>
End Sub
Now this works..when the classes/entities are generated, the replacement occurs correctly. However, I cannot get the same to work for ICollection
. An example of how this in generated in the entity class:
<Table("dbControl")>
Partial Public Class dbControl
Public Sub New()
dbController_Controls = New ObservableListSource(Of dbController_Controls)()
End Sub
Public Property ID As Long
<StringLength(2147483647)>
Public Property Name As String
Public Property ControlTypeID As Long?
Public Property ControlAssociationID As Long?
Public Overridable Property dbControlAssociation As dbControlAssociation
Public Overridable Property dbControlType As dbControlType
Public Overridable Property dbController_Controls As ICollection(Of dbController_Controls)
End Class
The relevant part of the EntityType.t4 appears to be:
foreach (var navigationProperty in entityType.NavigationProperties)
{
if (!first)
{
WriteLine(string.Empty);
}
else
{
first = false;
}
#>
Public Overridable Property <#= code.Property(navigationProperty) #> As <#= code.Type(navigationProperty) #>
<#
}
#>
End Class
However, there is no specific reference in the file to ICollection anywhere. Therefore a straight replace doesn't seem to be possible, unlike HashSet
Does anyone have any ideas?
I'm coming close to ditching Entity Framework all together tbh, as it's proving to be a little temperamental/infuriating! Any help appreciated