views:

107

answers:

2

Hello,

I'm trying to make an application in which both the developer and the end user are allowed retrieve data from a relational DB (chosen at runtime) without writing any SQL code at all (and preferably no string concatenations when interacting with the database). The purpose of the application is to two things: a GUI to an expression tree builder and XML serialization of trees generated by it.

I'd like to ask for some guidance or tips as to how to get things rolling. I don't want someone else to write this for me - this is my project I'll be the one writing the code.

So my questions are:

  1. Is it possible by only using only a connection string at run time to be able to create the object model and address the DB's elements in sets - for example a list of all of the tables, views, functions and sprocs?

  2. Can the elements of the aforementioned lists be used in the extension methods so I can build an expression tree?

  3. Can I use the Metadata Workspace class and the ItemCollections in order to retrieve those lists from the database having only the CSDL, SSDL and MDL files (but no Entity classes)?

  4. Can I use LINQ to XML in order to serialize the results of the expression tree or I will have to use some other serialization technology, specific to the Entity Framework? (Like in the example shown here: http://msdn.microsoft.com/en-us/library/bb738528.aspx)

PS: Here are some notes from my research so far: 1. For example the DataContext.GetTable() method (yes, the weakly typed one, not the generic) did not retrieve any data when the DataContext received only a connection string.

  1. I'm calling the EdmGen tool in order to generate the schema artifacts and so far I've read their attributes but I'm still trying to get some sort of list of elements which can be used in a lambda expression (tables for example)?

  2. If I understood correctly, in the Entity Framework I can use classes such as the Metadata Workspace and ItemCollections along with the EdmGen tool in order to create the necessary set of objects with which to represent the conceptual schema as an object model in the application.

I've browsed the Entity Framework Programming guide along the other related topics both here and on MSDN but so far I haven't found any information that is relevant to this scenario. Yesterday I got the "Programming Entity Framework" book and I hope that some of the answers lie in it. I'll update this question if I find any clues.

So, confused and still searching, I thank you in advance for any help on the matter.

Best regards, Borislav

A: 

These questions are heavy on theory and light on application, making it difficult to understand what you're trying to accomplish. Here's my best answers based on what I can understand from your questions. If you'll update with some detail on what your requirements are, I can refine them.


1: This sounds like "can my Entity Model be autogenerated at runtime with a connectionstring to include all my database objects?":

No. Your Entity Model is defined by your Entity Data Model (i.e. MyModel.edmx.) This is used to generate the Object Services class, MyModelEntities. The model must exist and be available in order for the Entity Framework Provider to execute queries against it.

2: If by "expression tree" you mean lambda or LINQ syntax:

Any collection object that implements IEnumerable, IQueryable, or other interfaces like these can be queried using LINQ (from i in EntitySet... select i) or lambda (.Where(x=>x.Id == 5)) syntaxes.

3: If you mean, can you use the EDM definition (CSDL, SSDL, MDL) by itself to query the database directly:

This is what LINQ to Entities does: translates LINQ queries into SQL queries. Why would you want to reinvent the L2E Provider?

4: Entity object serialization is a little weird (read:broken) in EF v1. The Entity objects come with a lot of EF baggage (they derive from EntityObject and carry extra properties) so serialization can be difficult. How well it works for you will depend on your entity objects and what you do with them once they're serialized.

Dave Swersky
Hi Dave,First of all thank you very much for the answers and the clarifications. I'd like to create an application that can connect to a database and have a GUI to building expression trees (in the form of lambda expressions) and finally serialize the results of the query to XML.However, I'm mostly trying to device this application as a "proof of concept": Can there be a .NET app that can allow full query abstraction and query serialization to any database.If such a thing is possible, I'd develop it further as a tool for my company.
Borislav T
The user would connects to a database, use the lambda expression-building GUI and create a query. Query results are in XML serialized form.This way lack of SQL knowledge and unsafe query concatenations are avoided.Example:var result = from TableA where TableA.Column1 = [value] select TableA.Column1, TableA.TableB.Column3 + TableA.TableB.Column4I know this might not be the best way to explain it but what I mean is to take advantage of a foreign key TableA has to TableB - for each row in TableA there are at can be null, one or more rows in TableB.
Borislav T
Regarding your questions:1. Yes, I wanted to see can the application connect to a database and at runtime and become aware of that database's EDM so that lamba expressions can be written without having statically named classes for each table or function.2. Yes, I meant lambda expressions.3. Answer is analogical to #1.4. Thank you for the remark on the serialization - I'm looking into LINQ to XML and I think I'll go with it.Aim: By knowing the relationships between tables, can I write a query expression that will produce hierarchical results (like "FOR XML" in MSSQL) ?
Borislav T
I hope I've clarified my motives behind this crazy-looking idea.Thank you once again for the answers so far - they really help me define what is possible and what isn't.All the best, Borislav
Borislav T
As a point of reference, have you checked out LINQPad? Google it, it's a free download. I'm curious as to whether it contains any of the functionality you're trying to build.
Dave Swersky
Truth be told LINQPad was one of the first things I installed when I began investigating LINQ. It's interface and the functionality of our company's other tool inspired me in the first place. Thanks for reminding me of it Dave - with all the hassle around the EF I didn't stop to think how LinqPad works. I also got a tip from on the MSDN so now I'm investigating the System.Data.Entity.Design namespace and the System.Data.EntityClient namespaces for more insight on how to get a hold of a custom ObjectContext at runtime. I'll post updates here as soon as I have some results.
Borislav T
A: 

Once again big thanks to dave for posting his thoughts on the matter.

Here's a summary of my research so far:

I'm abandoning LINQ to Entities in favor to LINQ to SQL - it looks like it will give me an easier time with this project.

So here are again my questions and the answers and comments I have till now:

  1. Is it possible by only using only a connection string at run time to be able to create the object model and address the DB's elements in sets - for example a list of all of the tables, views, functions and sprocs?

@Dave - actually this is sort of possible - I took a look at the "How LINQPad Work" section of LINQPad's official website and the answer was: Generate the classes at runtime using Reflection.Emit to create an in-memory footprint of methods, properties and their attributes and then create the classes based on them. Also, I go this tip from a moderator on MSDN: http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/471c8672-0a77-4186-b1d3-844abd8a822b So in a way I think it's possible to retrieve the Object Model at run time.

  1. Can the elements of the aforementioned lists be used in the extension methods so I can build an expression tree?

3.Can I use the Metadata Workspace class and the ItemCollections in order to retrieve those lists from the database having only the CSDL, SSDL and MDL files (but no Entity classes)?

I guess I didnt' ask the right question here - what I meant to say was: At run time you are aware that there is a table Table with columns Col1, Col2 and Col3. In a simple LINQ to SQL app the code would be

Table.Select(t => t.Col1, t.Col2, Col3)

However I'm looking for this: The user selects which columns to participate in the select so the final select would be something like this:

foreach(String UsersChosenColumn in TableColumnsArray)
   XDocumentXElement(UsersChosenColumn, (Table.Select(t => t.TableColumnsArray[UsersChosenColumn]))

However this cannot be done because finding out a column's name is not sufficient - knowing the column's type is what can get the job done. I'm looking into this right now but only in terms of LINQ to SQL, not LINQ to Entities - the logic may be different there.

@Dave: Here's a scenario for project: The user wants to get an XML on the following data: Orders.Name, Order.Price, Orders.Products.Name, Orders.Products.Manufacturer Where Orders.OrderID = 1234.

Here's what the output should be:

<Order>
 <Name>Some Order Name</OrderName>
 <Price>Some Price</Price>
  <Products>
   <Product>
     <Name>Some Product Name</Name>
     <Manufacturer>Shady Company Inc</Manufacturer>
   </Product>
   <Product>
     <Name>Some Product Name 2</Name>
     <Manufacturer>Another Company (TM)</Manufacturer>
   </Product>
  </Products>
</Order>

Since I've already put EF tags on this question I'll close it since now I'm looking for LINQ to SQL answers, no EF.

If I ask other quetions about this subject, I'll try to attach the approptiate LINQ to SQL tags to it.

All the best, Borislav.

Borislav T
@Dave - just one final question: What did you mean by "These questions are heavy on theory and light on application"?Sorry - I didn't quite understand you and I'd really like to know what you meant by that :).
Borislav T