User UserRoles Roles

Posts   
 
    
dvdstelt
User
Posts: 22
Joined: 06-Dec-2005
# Posted on: 16-Feb-2006 16:08:44   

Hi there,

I've fetched a collection of users, with an n:m relation to userroles. For example, Dennis has the roles "Manager", "Trainee" and "Developer".

The user.RolesViaUserRoles is read-only.

In the adapter scenario, how do I go about adding new roles and deleting existing ones? Do I actually delete the roles from the Roles collection, do I delete and add them to the UserRoles collection?

Thanks, Dennis

bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 17-Feb-2006 02:33:04   

Which roles are you wanting to delete? Are you wanting to remove Dennis from the Trainee role or are you wanting to remove the Trainee role altogether. If you are just wanting to remove Dennis from the Trainee Role then you would delete the Trainee UserRole from the UserRole collection of Dennis.

dvdstelt
User
Posts: 22
Joined: 06-Dec-2005
# Posted on: 17-Feb-2006 09:19:18   

Okay, easy enough... I wasn't thinking right, simple.

Now I've cleared the UserRole collection, created a new UserRole entity and set the user and the role properties.

But when looping through the user.RolesCollectionViaUserRoles then still the old values are there. Now of course I can use the user.UserRoles collection. But is there a way to automatically update the user.RolesCollectionViaUserRoles ?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39872
Joined: 17-Aug-2003
# Posted on: 17-Feb-2006 09:33:05   

dvdstelt wrote:

But when looping through the user.RolesCollectionViaUserRoles then still the old values are there. Now of course I can use the user.UserRoles collection. But is there a way to automatically update the user.RolesCollectionViaUserRoles ?

No, as that would be incorrect, as another thread might have deleted the intermediate entity, or might have added more intermediate entities. The only way to get that m:n collection to be refreshed is to refetch it.

Frans Bouma | Lead developer LLBLGen Pro
dvdstelt
User
Posts: 22
Joined: 06-Dec-2005
# Posted on: 17-Feb-2006 13:52:52   

Hmmm... My user has roles A and B. Now I add role C and want to delete role A.

How to go about this? I'm reading up on it and believe I have to create two collections. One for adding (or updating) and one for deletion. But that really sucks of course. I want to flag certain objects in my collection as new, updated or deleted.

I see SomeEntity.Fields.State which I can alter do deleted. Is that what it's for? Then in my lowest layer I can loop through the collection and see what objects I want updated and deleted. But if so, why isn't LLBLGen doing this for me?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39872
Joined: 17-Aug-2003
# Posted on: 17-Feb-2006 14:38:00   

dvdstelt wrote:

Hmmm... My user has roles A and B. Now I add role C and want to delete role A.

How to go about this? I'm reading up on it and believe I have to create two collections. One for adding (or updating) and one for deletion. But that really sucks of course. I want to flag certain objects in my collection as new, updated or deleted.

I see SomeEntity.Fields.State which I can alter do deleted. Is that what it's for? Then in my lowest layer I can loop through the collection and see what objects I want updated and deleted. But if so, why isn't LLBLGen doing this for me?

Use a unitofwork object to collect actions to perform and commit it in one go. You can't flag entities for deletion, the state is for informing you about the state of the entity.

M:N relations are readonly by definition, as they depend on OTHER relations' state and you don't know that state unless you requery from the db. They're also not automatically added because that wouldn't work with intermediate entities which have non-nullable fields. To keep code act the same way when you add such a field to an intermediate entity, you always have to update / insert / delete the intermediate entity yourself. Best way to do that is via a unitofwork object, simply add the entity to save or delete to the unitofwork object and commit it when you're done.

To avoid the question 'why can't I flag them as deleted', here's the answer: because YOU have to specify the order in which entities have to be deleted. This can't be determined UNLESS all data is read into memory. As that's not an option, YOU have to specify the order. Therefore flagging entities for deletion doesn't work, for example in entities which have a relation with self (employee -> employee (manager)).

Frans Bouma | Lead developer LLBLGen Pro
dvdstelt
User
Posts: 22
Joined: 06-Dec-2005
# Posted on: 17-Feb-2006 14:59:24   

Otis wrote:

Use a unitofwork object to collect actions to perform and commit it in one go. You can't flag entities for deletion, the state is for informing you about the state of the entity.

Only in my UI I know what should be deleted or not. If I insert everything into a nice collection, order or not, how can I be sure my datalayer (or o/r mapper) will delete every record in that order? I can't tell. And I certainly won't make a call for every delete, to be 100% sure.

I want to flag my objects for deletion or not, and let my datalayer (or o/r mapper) figure out what to do with the collection. Be able to send 10 objects in a collection, 4 of them marked as updated and 2 of them as deleted. The OR/M should figure out if it only needs to update two fields, if that's wiser performance wise, or whatever is the best decision.

I presume all developers on my team aren't completely stupid, and won't come into trouble when they delete a manager who has employees under him. That's like a cascading delete or a fk-reference that might fuck up and you should always be aware of those. I even might built in a intelligent function/sorter that figures out what to delete first.

Just a question, what will happen when I use the Fields.State for flagging my entities?

And why didn't you make it read-only if you say that's what that state is for?! simple_smile

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39872
Joined: 17-Aug-2003
# Posted on: 17-Feb-2006 15:28:31   

dvdstelt wrote:

Otis wrote:

Use a unitofwork object to collect actions to perform and commit it in one go. You can't flag entities for deletion, the state is for informing you about the state of the entity.

Only in my UI I know what should be deleted or not. If I insert everything into a nice collection, order or not, how can I be sure my datalayer (or o/r mapper) will delete every record in that order? I can't tell. And I certainly won't make a call for every delete, to be 100% sure.

True, so you can either add them to the Unitofwork or add them to a collection.

I want to flag my objects for deletion or not, and let my datalayer (or o/r mapper) figure out what to do with the collection. Be able to send 10 objects in a collection, 4 of them marked as updated and 2 of them as deleted. The OR/M should figure out if it only needs to update two fields, if that's wiser performance wise, or whatever is the best decision.

Like I said, don't try to do things differently than how you should do it. You can want that, but it's not going to work. If I add this kind of feature, it will lead to typical microsoft software: it works as long as you don't do anything complex but falls apart miserably when you do something more complex. The 'typical' solution applied to those situations then is to 'create a special case' for those complex issues, but you don't know up front if it's a complex issue or not, which leads to confusion during development and uncertainty and THUS improductivity. LLBLGen Pro tries to do things consistently, always in the same way, using the same methods, so if your situation or model slightly changes, you don't have to change your code everywhere, you know it will work, because it always works in all situations.

What you want IS what's called a unitofwork: you gather what you want to do in a unitofwork object. You decide what should be done, save and/or delete etc. and send it off to the db using a commit.

So what you want IS there, please use what's available to you.

I presume all developers on my team aren't completely stupid, and won't come into trouble when they delete a manager who has employees under him. That's like a cascading delete or a fk-reference that might fuck up and you should always be aware of those. I even might built in a intelligent function/sorter that figures out what to delete first.

Not to mitigate your coding capabilities, but you wont succeed in writing that sort routine. Neither can I, because it's not solvable. For example, if 2 or more paths lead from entity type A to entitytype Z, you can't implement cascading deletes (sqlserver gives up as well). The sorter also has to know all data of the entities involved, as it otherwise can't decide which entities to delete first. I had it done for entities IN memory, but it failed when it ran into entities in memory which didn't have their children in memory... and then these children have to be loaded into the graph as well. The sad thing with cascaded deletes is that you have to start with the leaves in a graph, though these leaves don't have to be in memory (often aren't). i.o.w.: it will fail in a lot of occasions, and that thus isn't useful. I rather have a routine which is deterministic than a routine which 'sometimes works' but randomly fails when something changes in the model and I then have to wade through all the code using that routine to see if it still works. Consistency saves your project. It might be leading to boring code, but c'est la vie.

Just a question, what will happen when I use the Fields.State for flagging my entities? And why didn't you make it read-only if you say that's what that state is for?! simple_smile

It's not readonly because generated code sometimes has to set it (selfservicing). I could of course create a method for that, but that's silly if you already have a property in the same class. The state is used for checking if you're reading from a deleted entity for example, so I'd not touch it as you don't need it. Use a unitofwork.

Frans Bouma | Lead developer LLBLGen Pro
Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 17-Feb-2006 15:30:58   

If I insert everything into a nice collection, order or not, how can I be sure my datalayer (or o/r mapper) will delete every record in that order?

UnitOfWork perform actions on entities in the same order you have inserted them into the UnitOfWork.

Please refer to the following thread: http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=3957

I want to flag my objects for deletion or not, and let my datalayer (or o/r mapper) figure out what to do with the collection. Be able to send 10 objects in a collection, 4 of them marked as updated and 2 of them as deleted.

We already have this feature: to have a collection of entities some of them marked for delete and some for update and some for insert. And in one step you can commit all those actions in the correct order. This collection we call it a UnitOfWork. UnitOfWork objects figure out the order in which actions have to be performed automatically: first Inserts, then Updates and then Deletes. Performed upon entities in the same order you have specified.

dvdstelt
User
Posts: 22
Joined: 06-Dec-2005
# Posted on: 20-Feb-2006 09:19:28   

Otis wrote:

dvdstelt wrote:

Otis wrote:

Use a unitofwork object to collect actions to perform and commit it in one go. You can't flag entities for deletion, the state is for informing you about the state of the entity.

Only in my UI I know what should be deleted or not. If I insert everything into a nice collection, order or not, how can I be sure my datalayer (or o/r mapper) will delete every record in that order? I can't tell. And I certainly won't make a call for every delete, to be 100% sure.

True, so you can either add them to the Unitofwork or add them to a collection.

Not true... Unitofwork will make sure inserts & updates occur before my deleted, as said in documentation. But not how my deletes will be processed. And my user interface should not know what a UnitOfWork is, my datalayer should.

Otis wrote:

I want to flag my objects for deletion or not, and let my datalayer (or o/r mapper) figure out what to do with the collection. Be able to send 10 objects in a collection, 4 of them marked as updated and 2 of them as deleted. The OR/M should figure out if it only needs to update two fields, if that's wiser performance wise, or whatever is the best decision.

Like I said, don't try to do things differently than how you should do it. You can want that, but it's not going to work. If I add this kind of feature, it will lead to typical microsoft software: it works as long as you don't do anything complex but falls apart miserably when you do something more complex.

That's for people who don't investigate in what the best solution is, and if the solution provided fits their needs. The fact that Microsoft doesn't really help (or at least didn't do so in the past) indeed sucks. But that doesn't mean you shouldn't include the option.

Otis wrote:

What you want IS what's called a unitofwork: you gather what you want to do in a unitofwork object. You decide what should be done, save and/or delete etc. and send it off to the db using a commit.

So what you want IS there, please use what's available to you.

But UnitOfWork can only be used in my datalayer (or business, if you're using the adapter from there). Not in my GUI! I just want to flag some stuff for deletion. In my case, some UserRoles should be removed, others should be added. Currently I have to make two calls, which is lousy because we'll get a chatty interface. The other solution is to provide one collection, flag each object, and then let the lower layers decide what actions to perform.

Otis wrote:

Not to mitigate your coding capabilities, but you wont succeed in writing that sort routine. <snip>

You're talking about a generic solution. I'm talking about just this one case. No matter WHAT we'll do, there HAS to be something that provides functionality to first delete all people under the manager, and only then delete the manger. Again, not generic, but custom made for this part of the functionality. But now I can't, because I can't flag! simple_smile

Otis wrote:

Just a question, what will happen when I use the Fields.State for flagging my entities? And why didn't you make it read-only if you say that's what that state is for?! simple_smile

It's not readonly because generated code sometimes has to set it (selfservicing). I could of course create a method for that, but that's silly if you already have a property in the same class. The state is used for checking if you're reading from a deleted entity for example, so I'd not touch it as you don't need it. Use a unitofwork.

The question still exists, can I use it? Or might it randomly be resetted to something else? Not taking into account the "RollBack" kind-of-functions.

And the UnitOfWork isn't supported in the WebServiceTemplates either, btw. Which is logical, because the UI should not know about them.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39872
Joined: 17-Aug-2003
# Posted on: 20-Feb-2006 11:47:22   

dvdstelt wrote:

Otis wrote:

dvdstelt wrote:

Otis wrote:

Use a unitofwork object to collect actions to perform and commit it in one go. You can't flag entities for deletion, the state is for informing you about the state of the entity.

Only in my UI I know what should be deleted or not. If I insert everything into a nice collection, order or not, how can I be sure my datalayer (or o/r mapper) will delete every record in that order? I can't tell. And I certainly won't make a call for every delete, to be 100% sure.

True, so you can either add them to the Unitofwork or add them to a collection.

Not true... Unitofwork will make sure inserts & updates occur before my deleted, as said in documentation. But not how my deletes will be processed. And my user interface should not know what a UnitOfWork is, my datalayer should.

Yes it does. The order in which you add them is the order in which they're deleted. A unitofwork is meant for tracking what should be done. It's a db agnostic object.

Please don't be stubborn in this: there's no way to do proper cascading deletes which always work without loading all the data in the graph into memory. I've tried to explain that to you my previous posting.

Otis wrote:

I want to flag my objects for deletion or not, and let my datalayer (or o/r mapper) figure out what to do with the collection. Be able to send 10 objects in a collection, 4 of them marked as updated and 2 of them as deleted. The OR/M should figure out if it only needs to update two fields, if that's wiser performance wise, or whatever is the best decision.

Like I said, don't try to do things differently than how you should do it. You can want that, but it's not going to work. If I add this kind of feature, it will lead to typical microsoft software: it works as long as you don't do anything complex but falls apart miserably when you do something more complex.

That's for people who don't investigate in what the best solution is, and if the solution provided fits their needs. The fact that Microsoft doesn't really help (or at least didn't do so in the past) indeed sucks. But that doesn't mean you shouldn't include the option.

Please... try to understand what the real problem is here. I've tried to explain to you that it can't be solved in a way which always works. So a 'solution' for this will fall apart in several situations. IMHO an unacceptable solution.

Otis wrote:

What you want IS what's called a unitofwork: you gather what you want to do in a unitofwork object. You decide what should be done, save and/or delete etc. and send it off to the db using a commit.

So what you want IS there, please use what's available to you.

But UnitOfWork can only be used in my datalayer (or business, if you're using the adapter from there). Not in my GUI! I just want to flag some stuff for deletion. In my case, some UserRoles should be removed, others should be added. Currently I have to make two calls, which is lousy because we'll get a chatty interface. The other solution is to provide one collection, flag each object, and then let the lower layers decide what actions to perform.

Otis wrote:

Not to mitigate your coding capabilities, but you wont succeed in writing that sort routine. <snip>

You're talking about a generic solution. I'm talking about just this one case. No matter WHAT we'll do, there HAS to be something that provides functionality to first delete all people under the manager, and only then delete the manger. Again, not generic, but custom made for this part of the functionality. But now I can't, because I can't flag! simple_smile

What are you suggesting, that I build in a piece of functionality just for you which won't work in a lot of situations? disappointed

I've explained before that there are several ways to accomplish what you want though if you want to do it only in the way you want to do it, then it might be a problem. I fear you're locked into a certain way of thinking and you have to snap out of that a bit to see the other options you might have. simple_smile I'll list a few below.

There are several ways to delete entities from the db: 1) - register a deleteentities directly call in a unit of work. For example to delete all employes which have an FK for managerid set to a given value X - register a delete entities directly call in the unit of work for deleting the manager.

2) - register a delete entity for every employee entity which has to be removed - register a delete entity for the manager

and of course you can call the delete actions also yourself. So all you do is pass the manager to the BL, in there you do: 3)


adapter.DeleteEntitiesDirectly("EmployeeEntity", new RelationPredicateBucket(EmployeeFields.ManagerID == myManager.ID));
adapter.DeleteEntity(myManager);

That's another option, 2 lines of code. That option 3) is IMHO preferable because you can send a list of ID's to the webservice for processing. This is what webservices are about: messaging. So you send a list of ids of managers to delete, and in the webservice you process them.

Otis wrote:

Just a question, what will happen when I use the Fields.State for flagging my entities? And why didn't you make it read-only if you say that's what that state is for?! simple_smile

It's not readonly because generated code sometimes has to set it (selfservicing). I could of course create a method for that, but that's silly if you already have a property in the same class. The state is used for checking if you're reading from a deleted entity for example, so I'd not touch it as you don't need it. Use a unitofwork.

The question still exists, can I use it? Or might it randomly be resetted to something else? Not taking into account the "RollBack" kind-of-functions.

And the UnitOfWork isn't supported in the WebServiceTemplates either, btw. Which is logical, because the UI should not know about them.

Why shouldn't the UI know about a unitofwork object? Proper webservice design requires messaging, so messages like 'RemoveManager' with an ID for the manager are appropriate, sending large buckets of objects across the wire isn't proper webservice design. UnitOfWork is a way to track what should be done, though it's not serializable to XML, correct, also because webservices only very recently became more solidly defined as what people should do and what they shouldn't do: e.g. no large buckets of data, but messages.

Frans Bouma | Lead developer LLBLGen Pro
dvdstelt
User
Posts: 22
Joined: 06-Dec-2005
# Posted on: 20-Feb-2006 13:22:38   

Otis wrote:

Yes it does. The order in which you add them is the order in which they're deleted. A unitofwork is meant for tracking what should be done. It's a db agnostic object.

I didn't know that, about the order of deletion. But that's what I ment! You're again holding a debate about me not being able to build a solution for cascading deletes, etc, etc. But the order-of-deletion-specified-by-order-of-adding-into-collection is exactly what I ment! simple_smile

I think on some things we're on the same level, it's just pretty hard discussing it via a forum and in English. Probably the Dutch-English thing again, which you discussed on your weblog once. sunglasses

Otis wrote:

dvdstelt wrote:

You're talking about a generic solution. I'm talking about just this one case. No matter WHAT we'll do, there HAS to be something that provides functionality to first delete all people under the manager, and only then delete the manger. Again, not generic, but custom made for this part of the functionality. But now I can't, because I can't flag! simple_smile

What are you suggesting, that I build in a piece of functionality just for you which won't work in a lot of situations? disappointed

Of course not! Manually flagging items for deletion is something that would not be just for me, everyone can use it.

Otis wrote:

dvdstelt wrote:

The question still exists, can I use it? Or might it randomly be resetted to something else? Not taking into account the "RollBack" kind-of-functions.

And the UnitOfWork isn't supported in the WebServiceTemplates either, btw. Which is logical, because the UI should not know about them.

Why shouldn't the UI know about a unitofwork object? Proper webservice design requires messaging, so messages like 'RemoveManager' with an ID for the manager are appropriate, sending large buckets of objects across the wire isn't proper webservice design. UnitOfWork is a way to track what should be done, though it's not serializable to XML, correct, also because webservices only very recently became more solidly defined as what people should do and what they shouldn't do: e.g. no large buckets of data, but messages.

Proper webservice design in a SO(A) world, and I don't give a *&$ about SO in my case. Service Orientation is for communicating with external systems, in my beliefs. And I'm not working with external systems in my communication.

But the UnitOfWork is specifically a database orientated unit of work. And my UI should not be aware of things like that. But that's a totally other discussion, that we'll quit this instance, because it doesn't add anything simple_smile

Let's get to another question. What do you suggest I'd use, when I'm not able to use UnitOfWork from my UI and I make calls over webservices?! smile

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39872
Joined: 17-Aug-2003
# Posted on: 20-Feb-2006 14:28:55   

dvdstelt wrote:

Otis wrote:

Yes it does. The order in which you add them is the order in which they're deleted. A unitofwork is meant for tracking what should be done. It's a db agnostic object.

I didn't know that, about the order of deletion. But that's what I ment! You're again holding a debate about me not being able to build a solution for cascading deletes, etc, etc. But the order-of-deletion-specified-by-order-of-adding-into-collection is exactly what I ment! simple_smile

Ok, then we finally getting somewhere. simple_smile That wasn't clear to me though, I thought you tried to get an order of deletes in a random collection.

Otis wrote:

dvdstelt wrote:

You're talking about a generic solution. I'm talking about just this one case. No matter WHAT we'll do, there HAS to be something that provides functionality to first delete all people under the manager, and only then delete the manger. Again, not generic, but custom made for this part of the functionality. But now I can't, because I can't flag! simple_smile

What are you suggesting, that I build in a piece of functionality just for you which won't work in a lot of situations? disappointed

Of course not! Manually flagging items for deletion is something that would not be just for me, everyone can use it.

But what will a 'flag' do? The main problem with adding features is that it has to be absolutely clear what a feature does and it has to work always. The thing is that in the past we've been burned by features being added but later on a different approach would have been way better but it then was too late (IValidator debacle) or for example that it confused users what to use in which situation.

Otis wrote:

dvdstelt wrote:

The question still exists, can I use it? Or might it randomly be resetted to something else? Not taking into account the "RollBack" kind-of-functions.

And the UnitOfWork isn't supported in the WebServiceTemplates either, btw. Which is logical, because the UI should not know about them.

Why shouldn't the UI know about a unitofwork object? Proper webservice design requires messaging, so messages like 'RemoveManager' with an ID for the manager are appropriate, sending large buckets of objects across the wire isn't proper webservice design. UnitOfWork is a way to track what should be done, though it's not serializable to XML, correct, also because webservices only very recently became more solidly defined as what people should do and what they shouldn't do: e.g. no large buckets of data, but messages.

Proper webservice design in a SO(A) world, and I don't give a *&$ about SO in my case.

That's great but it would be a good thing to keep in mind, because sooner or later you WILL hit the wall, and it's never nice to hit walls wink

Service Orientation is for communicating with external systems, in my beliefs. And I'm not working with external systems in my communication.

well, you opted for webservices so you're doing SOA. I explained earlier that in your situation it also might be better to use remoting, as it's easier, at least, you can easier embed it in a lower level of the application stack.

Let's get to another question. What do you suggest I'd use, when I'm not able to use UnitOfWork from my UI and I make calls over webservices?! smile

If I understand you correctly, you want to flag managers which have to be deleted, correct? So the employees referring to these managers have to be updated/deleted as well? I then would compile a list of ID's of these managers and send that to the webservice method, which in turn performs the proper actions on the db: bulk deleting employees and then bulk deleting managers (using FieldCompareRange predicates) or bulk updating employees by settign their FK field to NULL.

IMHO that's the best solution, because you then call into the service to do something for you, and as I illustrated above, the service can do that in very few lines of code. The advantage is that you send very little data over the wire, and you keep everything abstracted.

Frans Bouma | Lead developer LLBLGen Pro
dvdstelt
User
Posts: 22
Joined: 06-Dec-2005
# Posted on: 20-Feb-2006 22:12:47   

Otis wrote:

But what will a 'flag' do? The main problem with adding features is that it has to be absolutely clear what a feature does and it has to work always. The thing is that in the past we've been burned by features being added but later on a different approach would have been way better but it then was too late (IValidator debacle) or for example that it confused users what to use in which situation.

Well, then call it "WhateverEntity.Fields.ManuallySettedState = State.Delete" or something wink

But a DataSet also has a flag, if I remember correctly, and no one is questioning what it really does.

Otis wrote:

dvdstelt wrote:

Proper webservice design in a SO(A) world, and I don't give a *&$ about SO in my case.

That's great but it would be a good thing to keep in mind, because sooner or later you WILL hit the wall, and it's never nice to hit walls wink

Why do you think I'm going to hit a wall here?

Otis wrote:

dvdstelt wrote:

Service Orientation is for communicating with external systems, in my beliefs. And I'm not working with external systems in my communication.

well, you opted for webservices so you're doing SOA.

OUCH !!! frowning frowning frowning frowning

I hope no SO advocate sees this, because the entire community is going to fall over you now! wink

But seriously, webservices != service orientation

I had my share of debate with Richard Turner (Microsoft) for example, who said I can never ever be 100% sure the webservice-interface I'm developing would not be used by other systems. Believe me, I am and I know I can be sure on this one. Richard Turner still tells me to use messages instead of sending objects over the wire.

On the other hand though, I've recently read in an Indigo book, that objects being serialized into pure xml, are ok in a service orientated world. I doubt it'd be that way with complex object graphs. Where LLBLGen supplies an EntityCollection, there's no one who can ever tell what's going over the wire after a nice fetch with a lot of prefetch paths. And that's definitly not service orientated! simple_smile

Otis wrote:

I explained earlier that in your situation it also might be better to use remoting, as it's easier, at least, you can easier embed it in a lower level of the application stack.

I don't care. I might want to convert everything to WCF and ASMX 2.0 and WSE 3.0 are much better choices then.

Otis wrote:

dvdstelt wrote:

Let's get to another question. What do you suggest I'd use, when I'm not able to use UnitOfWork from my UI and I make calls over webservices?! smile

If I understand you correctly, you want to flag managers which have to be deleted, correct?

No, you're still into the cascading deletes here smile

I have one user and 5 different roles I can place him in. I have the UserRole intermediate table (and thus entity) and when I fetch the user, it has already 3 roles assigned to. I want to remove 2 roles, and add 1 role it wasn't assigned to before.

So instead of role1, role3 and role4, I want role1 and role2 assigned to the user. Two deleted, one insert. What is the best way to solve this?

In my opinion, flag role3 and role4 for deletion (of course in the UserRole collection, not the actual Role collection and/or table) and insert role2 into the collection. Role2 will be automatically marked as new.

Thanks in advance.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39872
Joined: 17-Aug-2003
# Posted on: 20-Feb-2006 23:39:45   

dvdstelt wrote:

Otis wrote:

But what will a 'flag' do? The main problem with adding features is that it has to be absolutely clear what a feature does and it has to work always. The thing is that in the past we've been burned by features being added but later on a different approach would have been way better but it then was too late (IValidator debacle) or for example that it confused users what to use in which situation.

Well, then call it "WhateverEntity.Fields.ManuallySettedState = State.Delete" or something wink

But a DataSet also has a flag, if I remember correctly, and no one is questioning what it really does.

Yeah, well, a dataset is tabular data, not a graph of objects.

Otis wrote:

dvdstelt wrote:

Proper webservice design in a SO(A) world, and I don't give a *&$ about SO in my case.

That's great but it would be a good thing to keep in mind, because sooner or later you WILL hit the wall, and it's never nice to hit walls wink

Why do you think I'm going to hit a wall here?

Because webservices are limited: no polymorphism in your return type, and the XML can become a bottleneck in performance. Also the dreaded route via wsdl.exe and the stub is cumbersome. (IMHO).

Otis wrote:

dvdstelt wrote:

Service Orientation is for communicating with external systems, in my beliefs. And I'm not working with external systems in my communication.

well, you opted for webservices so you're doing SOA.

OUCH !!! frowning frowning frowning frowning

I hope no SO advocate sees this, because the entire community is going to fall over you now! wink

haha, yeah right simple_smile . Webservices ARE a way to do soa, IMHO. If you use webservices, it's IMHO impossible to say you're not busy with SOA, even if you don't want that to be true.

But seriously, webservices != service orientation

Frankly I don't care, wordgames aren't my preferred way of spending time, but to me it's insane to use webservices for something else than SOA.

I had my share of debate with Richard Turner (Microsoft) for example, who said I can never ever be 100% sure the webservice-interface I'm developing would not be used by other systems. Believe me, I am and I know I can be sure on this one. Richard Turner still tells me to use messages instead of sending objects over the wire.

And he's right.

On the other hand though, I've recently read in an Indigo book, that objects being serialized into pure xml, are ok in a service orientated world. I doubt it'd be that way with complex object graphs. Where LLBLGen supplies an EntityCollection, there's no one who can ever tell what's going over the wire after a nice fetch with a lot of prefetch paths. And that's definitly not service orientated! simple_smile

Exactly, and you therefore should think how you would setup your distributed application. The lower you place the remote layer in teh application stack, the more data you'll have to pass to /from the remote layer.

Otis wrote:

dvdstelt wrote:

Let's get to another question. What do you suggest I'd use, when I'm not able to use UnitOfWork from my UI and I make calls over webservices?! smile

If I understand you correctly, you want to flag managers which have to be deleted, correct?

No, you're still into the cascading deletes here smile

I have one user and 5 different roles I can place him in. I have the UserRole intermediate table (and thus entity) and when I fetch the user, it has already 3 roles assigned to. I want to remove 2 roles, and add 1 role it wasn't assigned to before.

So instead of role1, role3 and role4, I want role1 and role2 assigned to the user. Two deleted, one insert. What is the best way to solve this?

In my opinion, flag role3 and role4 for deletion (of course in the UserRole collection, not the actual Role collection and/or table) and insert role2 into the collection. Role2 will be automatically marked as new. Thanks in advance.

1) create an Entity Collection, add UserRole objects for role 3 and 4 to that collection 2) remove them from the UserRoles collection in user 3) add userrole object for 2 4) send user and entitycollection to service.

Remember, this is for webservices ONLY. If you would have used remoting, you would have been able to use a unitofwork object.

Frans Bouma | Lead developer LLBLGen Pro