DLINQ Queries and observations
I have the following queries/Observations about DLINQ.
1. I could not find any direct way of handling many to many relations.
Suppose if User and Role are related by a join table UserRole then I should
be able to have a collection of Roles in User and vice versa. Which i think
is not possible in DLINQ. (Please correct me if I am wrong)
2. State management is handle outside entities. In scenareos where a client
grabs a entity from a WS , makes some changes and post it back to the ws for
updation, how is the DLINQ framework handle optimistic locking? Why can't state be maintained in the entity itself? maybe by a base class, we already call a delegate in the setters right?
3. How do I provide optimizer hints in my DLINQ query? I have seen that thw
Query optimize taking wrong desicions white choosing join strategies and I
would like to override it. I would like to have this power without loosing the compile time checking facility.
4. I always felt the the VS WS proxy generator unnecessarily (re)defined the
custom entities in the generated proxy. I should be able to tell the VS to
use my definitions instead. ( this point is related to point 2 ..without this point 2 will be impossible)
(I had posted it in another group, but I just wanted to get a broader view)
whery interesting questions.
has nobody answers?
1. I think many-to-many is not supported today. If they don't support it in the final release then DLINQ will be a total joke!
2. DLINQ Team is aware of problem of state management in remoting scenario. Basically, the old values of persistent fields need to be serialized with the entity. Essentially there needs to be a client piece that tracks state changes in the entities and just sends the changes back to the server.
3. Dunno. Known issue.
4. The larger question is should you be referring to your entities in a ws proxy? Your service should only expose messages not entities. I think what is needed is a way to easily create DTO's and Service-type messages. Essentially we need a way to transform Domain entities to service messages. Thats why doing a projection over an in-memoy object graph is so important.
Dave>
The larger question is should you be referring to your entities in a ws proxy? Your >service should only expose messages not entities. I think what is needed is a way to easily >create DTO's and Service-type messages. Essentially we need a way to transform Domain >entities to service messages. Thats why doing a projection over an in-memoy object graph is >so important.
Rana> Agreed Dave, but sometimes I would like my messages to be intelligent (may not be in true WS spirit) such as to do some validation at client side, sorting capability, capability to bind to UI controls, state management (;-)) etc. MS did just that with Datasets and they taught the proxy generator about dataset ;-).
By the way, how does datasets fits in the scheme of things of DLINQ?
Rana Basu wrote: |
but sometimes I would like my messages to be intelligent (may not be in true WS spirit) such as to do some validation at client side, sorting capability, capability to bind to UI controls, state management (;-))
|
|
Versant did exactly this with their Versant Open Access .NET product (now Vantec). Its a shortcut instead of doing it the long way (entity > message > entity on the client). Maybe you should be looking at remoting instead of web services? Rana Basu wrote: |
By the way, how does datasets fits in the scheme of things of DLINQ?
|
|
Hopefully, not at all. There are some improvements to DataSet (TableAdapter, binary serialization) in 2.0. But when you already have persistent entities then where would they fit in your architecture? Certainly not anywhere below your business objects. The only place I use Datasets are up in my presentation layer. I sometimes transform the entities into datatables that I can bind to, when I have to reshape my domain model into a presentation model. I then have to write the changes in the datatable back the entities before persisting them.Hi Dave,
This is the part I have a problem with. It sounds like I do things in much the same way as Rana. I pass DataSets, serialized to XML, through Web Services. I don't quite see how this scenario will fit in with DLINQ.
Microsoft doesn't advertise it much, but the role of the DataSet is very much reduced with DLINQ. There are no DataSets between your business objects and the database.
For Web services, the business objects have to be serialized into some sort of XML. You can create Datasets out of your business objects to send them over the wire (although I probably wouldn't). In this case the DataSet is just a DTO.
The only standard for DTO's that I know of is Service Data Objects, but something tells me that Microsoft will probably come up with their own standard for serializing state over web services.
So, in the end, you can still use the DataSet as a DTO if you want to do the extra work.
Here are some quick answers:
1. You will need to model it with a class mapping to the "table in the middle" with the LINQ preview.
2. We are working on the remoting and original value handling aspects. Self-contained entities is one of several options.
3. You can use the SQL escape hatch DataContext.ExecuteQuery() for that. Even for SQL, you should use hints as a last resort. It is better to trust the SQL query optimizer since the profile or the data, how it stored/indexed and the abilities of the optimizer can change over time rendering hints that were once useful suboptimal. DLinq is one step further removed from SQL so SQL hints may have limited use.
4. This is not really a LINQ issue so it is best discussed elsewhere.
HTH
Dinesh Kulkarni
Program Manager - The LINQ Project
Dave,
I guess my point is that since DLINQ is server-side, and I'm accessing server-side stuff through a Web Service, that original instance of the DLINQ DataContext object won't be there when I pass my data back through the Web Service to be updated. There will need to be some other mechanism for recognizing what has changed.
Dinesh,
You said that you "are working on the remoting and original value handling aspects. Self-contained entities is one of several options." Does "remoting" include Web Services too? Do you want to divulge any hints as to how you're planning to make this work?
Thanks,
(Repeating some answers from our web-chat with C# MVPs):
Bonnie's point about not maintaining state on the server is correct.
As for the question directed to me: I do mean all different forms of sending data across tiers (and machines): web services included. It is still under design so not much to discuss here today.
Thanks.
Dinesh Kulkarni
I guess my point is that since DLINQ is server-side, and I'm accessing server-side stuff through a Web Service, that original instance of the DLINQ DataContext object won't be there when I pass my data back through the Web Service to be updated. There will need to be some other mechanism for recognizing what has changed.
|
|
Yes. Old values and current values need to be sent, same as what DataSet gives you today. Of course an intelligent client will only send back the changes (analagous to DataSet.GetChanges), not all the business objects. An intelligent server piece will merge the changes with the current state of the business objects (analagous to DataSet.Merge).
Nothing has changed. All the same principles apply.
Dave,
I think we may be talking apples and oranges here.
| Old values and current values need to be sent, same as what DataSet gives you today. Of course an intelligent client will only send back the changes (analagous to DataSet.GetChanges), not all the business objects |
|
Whether I send back either Old Values/New Values or only Changes, it isn't going to matter, from what I understand of how DLINQ currently works. Granted, they're working on changing it, but right now, the changes to your data is tracked by the DLINQ DataContext. This will not work in a client/server Web Service scenario.
| An intelligent server piece will merge the changes with the current state of the business objects (analagous to DataSet.Merge). |
|
I don't follow you there ... how is there any state? Server-side Biz Objects will have no state. Not with Web Services anyway.
This will not work in a client/server Web Service scenario.
|
|
A bit of pseudo code should clear it up. This is the server side code to update an order:
| | public void SyncOrder(DataTransferObject DTO) { using (Northwind db = new Northwind("c:\\northwind\\northwnd.mdf");)) { // get the order from the database var ord = db.Orders.First(o => o.OrderID == DTO.id); //update the order with changes from the client ord.Date = DTO.Date; //TODO: update all properties, children, etc. //save changes back the datbase db.SubmitChanges(); } }
|
Of course I have ignored all the details and concurrency issues if there was a collision. This method is completely stateless.
Server-side Biz Objects will have no state
|
|
Business objects, no matter if they live on the server or the client always have state. They have state for as long as they are alive. The client code that consumes them (Winform client or Web service) is what is stateful or stateless. The Order business object above is stateful but it is consumed by a stateless service method. The stateful business object has to be retrieved and saved to the database on each server call. That is the definition of statefulness.
Dave,
Thanks for the pseudo-code ... I see what you were trying to say and it makes sense now. Of course, it kinda sucks that all that would have to be done manually, but then I already do a lot of manual stuff in my DataAccess classes currently with 1.1, so I guess I'm used to it.
| Business objects, no matter if they live on the server or the client always have state. They have state for as long as they are alive < snip> The stateful business object has to be retrieved and saved to the database on each server call. That is the definition of statefulness |
|
Yes, of course, that's what I meant also. I guess I just misinterpreted what you said earlier. Thanks!
Seeing .First(), have you seen an .Only()? In this case, I think it would be more correct -- there's the problem of finding duplicated IDs in a system which may not be enforcing the uniqueness of the key.
[If not, then this would be a suggesting to Dinesh -- Only() -> throws an exception if there is more than one item that satisfies the predicate, else behaves as First().]