Filling Entity/Collection from DataTable / DataSet

Posts   
 
    
trevorg
User
Posts: 104
Joined: 15-Nov-2007
# Posted on: 08-Oct-2008 01:08:05   

1) Does the code below seem like a good way to do this, or is there a better approach? 2) See the inline questions in 2nd function below

   Public Shared Function LoadCollection(Of llbEntityType As {EntityBase, New})(ByVal entityCollection As EntityCollectionBase(Of llbEntityType), ByVal sourceTable As DataTable) As EntityCollectionBase(Of llbEntityType)
        For Each row As DataRow In sourceTable.Rows
            Dim newEntity As New llbEntityType
            LoadEntity(newEntity, row)
            entityCollection.Add(newEntity)
        Next
        Return entityCollection
    End Function

    Public Overloads Shared Sub LoadEntity(Of llbEntityType As {EntityBase, New})(ByRef entity As llbEntityType, ByVal row As DataRow)
        For Each fld As IEntityField In entity.Fields
            ' Can I load like this:
            entity.SetNewFieldValue(fld.Name, row.Item(fld.SourceColumnName))
            ' I assume this is not the right way:
            entity.Fields(fld.Name).ForcedCurrentValueWrite(row.Item(fld.SourceColumnName))

            'Question: Am I going to have a problem with the entity knowing whether it needs to do 
            'an update or insert? Is there some hidden intelligence it can use for that (in case I don't necessarily know for some reason)
            'It would be very inefficient of course but thats ok.  This might work sometimes:
            '           entity.IsNew = (row.RowState = DataRowState.Added)
        Next
    End Sub

3) I am using this at least in part to overcome the difficulties of using WebServices, (so, I am passing the modified datatables back to a webservice, Load into entites, Save); does this seem reasonable? 4) Might this type of thing be introduced into the core product (although it is obviously a bit dangerous, "use at your own risk" code) 5) Is there a way that **based on a table name **I can find the corresponding LLB entity type (so i could write a function that just accepts a datatable, and based on datatable.name, it could construct the proper LLB collection type, fill it with LLB Entities, and then save the collection). [Hope you understand what I mean]

Note: Here's the above code in c# (via a convertor, so not sure if it is correct):

public static EntityCollectionBase<llbEntityType> LoadCollection<llbEntityType>(EntityCollectionBase<llbEntityType> entityCollection, DataTable sourceTable) where llbEntityType : EntityBase, new() 
{ 
    foreach (DataRow row in sourceTable.Rows) { 
        llbEntityType newEntity = new llbEntityType(); 
        LoadEntity(newEntity, row); 
        entityCollection.Add(newEntity); 
    } 
    return entityCollection; 
} 

public static void LoadEntity<llbEntityType>(ref llbEntityType entity, DataRow row) where llbEntityType : EntityBase, new() 
{ 
    foreach (IEntityField fld in entity.Fields) { 
        // Can I load like this: 
        entity.SetNewFieldValue(fld.Name, row.Item(fld.SourceColumnName)); 
        // I assume this is not the right way: 
        entity.Fields(fld.Name).ForcedCurrentValueWrite(row.Item(fld.SourceColumnName)); 
        
        //Question: Am I going to have a problem with the entity knowing whether it needs to do 
        //an update or insert? Is there some hidden intelligence it can use for that (in case I don't necessarily know for some reason) 
        //It would be very inefficient of course but thats ok. This might work sometimes: 
        // entity.IsNew = (row.RowState = DataRowState.Added) 
    } 
}

The reason I ask this is two parts: - Web Services seem to be more trouble than they are worth (but corporate architecture people LOVE them, even when there is absolutely no point to it whatsoever) - Microsoft seems to have gone backwards in some ways - with traditional ADO (or MS Access), you could write a query with multiple joins and bind that to a grid and you had full read, write, update, delete functionality....no code, no problem. Now, it seems if you go anywhere beyond the simple Hello World demos they do in their presentations you run into problem after problem.

Some of this gets a bit back into the database agnostic dynamic sql conversation I raised in one of my earlier posts, which is contrary to the principles of LLBLGen, but sometimes it is necessary. I think my second point is that, the old ADO support for supporting updates against datasources involving joins was awesome, and MS seems to have dropped it, is this something LLB could support? Compared to figuring out LINQ, this should be a walk in the park for Frans, no?? wink

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 08-Oct-2008 12:46:25   

1) Does the code below seem like a good way to do this, or is there a better approach?

Yes

2) See the inline questions in 2nd function below

' Can I load like this: entity.SetNewFieldValue(fld.Name, row.Item(fld.SourceColumnName)) ' I assume this is not the right way: entity.Fields(fld.Name).ForcedCurrentValueWrite(row.Item(fld.SourceColumnName))

The first way is the way to go. Don't "Force" the value.

        'Question: Am I going to have a problem with the entity knowing whether it needs to do 
        'an update or insert? Is there some hidden intelligence it can use for that (in case I don't necessarily know for some reason)
        'It would be very inefficient of course but thats ok. This might work sometimes:
        '           entity.IsNew = (row.RowState = DataRowState.Added)

If it was not fetched from the database the entity will always be treated as new unless you set the entity.IsNew to false.

3) I am using this at least in part to overcome the difficulties of using WebServices, (so, I am passing the modified datatables back to a webservice, Load into entites, Save); does this seem reasonable?

Have you looked at using DTOs? There are some 3rdParty templates on the Forums to generate DTOs for the entities. Please search for DTO in the Forums search page.

Will get back to you on the other questions.

trevorg
User
Posts: 104
Joined: 15-Nov-2007
# Posted on: 09-Oct-2008 03:18:11   

I think this: 5) Is there a way that based on a table name I can find the corresponding LLB entity type (so i could write a function that just accepts a datatable, and based on datatable.name, it could construct the proper LLB collection type, fill it with LLB Entities, and then save the collection). [Hope you understand what I mean]

...might be further complicated by subclasses/polymorphic fetches....ie: if I load a collection and project to a dataset, I end up with one DataTable per subclass....so when wanting to reload these back into EntityObjects, I need to instantiate the proper type in prder to load from the datatable.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 09-Oct-2008 11:46:38   

5) Is there a way that based on a table name I can find the corresponding LLB entity type (so i could write a function that just accepts a datatable, and based on datatable.name, it could construct the proper LLB collection type, fill it with LLB Entities, and then save the collection). [Hope you understand what I mean]

Knowing what you are fetching, the dataTable could be named with the entityName so you can either use something like

Activator.CreateInstance(typenameAsString);

to instatiate the entity.

trevorg
User
Posts: 104
Joined: 15-Nov-2007
# Posted on: 09-Oct-2008 16:52:36   

Ya, although theoretically I may not always know.

I haven't looked at the DTO templates yet...do you happen to know, are these types of issues that I'm having all adressed in the templates, or is a lot of manual coding work still required.

Walaa avatar
Walaa
Support Team
Posts: 14950
Joined: 21-Aug-2005
# Posted on: 09-Oct-2008 19:24:07   

Most if not all of it is covered if you use DTOs, as all you have to do is call the methods to get you the DTO object out of the Entity and viceVersa (2-way conversion).