Поделиться через


DLinq Mapping: External Or Not (Attributes or XML file)

At PDC (and before that on ObjectSpaces project), this was a hot discussion topic. What approach is better: attributes or external source like an XML file. I would like to open up this topic beyond the 1:1 conversations at PDC to the blogosphere. I will start with a small backgrounder and you tell us which one makes more sense to you.

Advantage attributes

  1. Really simple for the basic cases. No need to create or consult (e.g. for debugging) another source file. Works with current tools that handle attributes.
  2. Easy access to mapping metadata without additional APIs.
  3. Requires recompilation for changes. No, this is not a mistake. Despite situations that make recompilation problematic, usually having a compiler check things is better than getting run-time exceptions

Advantage external mapping

  1. Same classes can be mapped to multiple data models using different mapping files (this includes different DB/table/column names, different server vendors etc.)
  2. Avoids clutter in source code, especially in case of complex mapping
  3. Hides database-specific information from users of object model
  4. Some schema changes can be handled without recompilation (IMO, the class of changes that can be handled is often exaggerated)

Of course, a natural question is why not support both? Well, as a user, which one should I choose? How do I decide? Do I need to learn both ways? As builders of the ORM component, do we split out resources on two things that achieve more or less the same result instead of focusing on one?

So what do you think. Do you have compelling scenarios that cannot be handled using one of the options?

Comments

  • Anonymous
    September 19, 2005
    Dinesh, I think you might remember who I am (I'm on the customer council, and was a little harsh when it came to ObjectSpaces).

    Personally, I really like using attributes. I agree that complex mappings might make for cleaner source code, but keeping the source code simple doesn't mean that the complexity is erased.

    In that case, out of sight doesn't equate to out of mind. In the cases of additions or deletions (of fields or relations) to your schema, you are going to have to change the source code anyways, since those fields will no longer be valid, and your assumptions will have changed.

    The only advantage from your list that I see as being valid is #1. However, I think that with the right design of the attributes, you can achieve this easily using an attribute-based approach.

  • Anonymous
    September 19, 2005
    I think mapping the same types to multiple data models is a compelling reason. I frequently use my existing mappers to map the same types to different schemata for server side and smart client stores. I may also wish to map the same types to both XML and relational DB schemata.

    I also think that isolating business objects from any knowledge of the database is a compelling reason in and of itself.

    Compile-time checking of external mapping information is still definitely possible, and in fact I would expect it from a tool as sophisticated as Visual Studio. Let us put the mapping information in a separate project, in some kind of mapping files, and you can compile that to ensure that it makes sense. You could even provide compile-time checking against the actual database metadata.

  • Anonymous
    September 19, 2005
    I'm a fan of external. My own ORM tool (http://savannah.nongnu.org/projects/nrdo) uses external files for one very important reason: it actually builds the database using the information in those files, as well as creating relevant indexes, foreign keys, etc. At compile time the schema is checked and if any changes are needed (add/drop columns, indexes, tables, etc) the changes are made accordingly. Oh, and it also generates the C# source files.

    While it's possible to put enough information into attributes to build the database from it, you'd be hard-pressed to do that and still make the files as easy to write as an external file can be.

    It goes the other way, too. You'd be hard-pressed to get enough information out of the database structure alone to be able to create classes that represent that structure in the most natural way - especially it's not possible to tell what "get" methods to provide based on the database structure alone (although this particular limitation becomes less important with Linq because it allows the programmer to specify an arbitrary where clause, there are others).

    Using an external file and building both the database and code from that makes life very easy, in that you only have to define your table structure once, rather than building the database, then writing a class, then providing a means (attributes or mapping file) to connect the two together. It also lets the table structure itself be in source code control, and makes moving schema changes from dev to live very automatic.

    Attributes can't do any of this :)

  • Anonymous
    September 19, 2005
    The only external mapping scenarios that I've ever seen as compelling were for database providers and database command wrapping when the database provider (and, therefore, SQL syntax) may change.

    So if the entity update command needs to vary, then some way needs to be provided for it. Perhaps [UpdateAttribute(providerName, command)], [UpdateAttribute(providerName, xmlFile, commandId)] would be suitable overloads?

  • Anonymous
    September 19, 2005
    I have quite a few people that use my WilsonORMapper for database independence because they create/sell products that must support multiple database vendors. At times this requires slightly different mappings for different databases, even though the code is the same in many of those cases. Probably even more significant though is the number of people that must support their database tables having a configurable prefix so that collisions with existing database tables do not occur. In this case the table names, and possibly even field names since customers can be peculiar and they are paying the bills, are determined by the end customer -- simple to handle in an external mapping file. I also know of cases in highly regulated environments (medical/FDA) where a change in the source code that would require a recompile is simply not legally allowed, even though an external "configuration" is allowed -- and the law doesn't care whether or not you think that is just as risky or even more so. There are also cases where you make a reusable set of domain objects that you use in multiple projects with different tables -- something which external mappings make easily reusable, but internal attributes that mark something external to the class make more difficult.

    So the only advantages I see to internal attributes is that some people (but not all) view them as simpler, that they reduce your need to have another file (which no one argues for in most other cases), and makes things easier for tools (which a tool issue, and isn't really true anyhow). I'm more than willing to admit that some people prefer internal mappings however, but in that case you should also be more than aware that more people seem to prefer external mappings -- so you either have to allow either, or require the one that solves more problems without creating more in the process. And while many people may never see the types of problems that others have, those of us that work in O/R Mapping are very much familiar with the very real-world problems that external mappings solve.

  • Anonymous
    September 19, 2005
    I think the important scenario you are forgetting is when you don't have a consistent object store. I might want to pull data out of an XML file on my PDA, a SQL Server DB on my server, and a WinFS store on my client. Who would want to have to ship a different set of DLLs for each one?

    While it is fine for my custom in-house app which will only ever run against SQL Server, anything that goes out to clients will need to be able to configure the data access layer at run-time.

  • Anonymous
    September 19, 2005
    Dinesh:
    Aside from the advantage of loose coupling (think of a query over multiple db scenario), the biggest benefit of an external mapping file is less corruption of the language. As you may have noticed, in the Java world annotations are evolving into an expression language of its own and many people commented on how horrible it is and how it messes up readability of the programs.
    What I would like to see is limited custom attributes for mapping, external mapping files with deep integration with Intellisense for complex scenarios and a good way to deploy compiled mapping files along with the dll's and exe's.
    Does this make sense?
    Soumitra

  • Anonymous
    September 19, 2005
    Dinesh:
    Aside from the advantage of loose coupling (think of a query over multiple db scenario), the biggest benefit of an external mapping file is less corruption of the language. As you may have noticed, in the Java world annotations are evolving into an expression language of its own and many people commented on how horrible it is and how it messes up readability of the programs.
    What I would like to see is limited custom attributes for mapping, external mapping files with deep integration with Intellisense for complex scenarios and a good way to deploy compiled mapping files along with the dll's and exe's.
    Does this make sense?
    Soumitra

  • Anonymous
    September 19, 2005
    An obvious reason is that external files are "against the grain" for .NET development. It creates an impedance between files that collectively specify a class.

    Attributes are also strongly-typed. I realize that the XML designer in VS2005 is extensible and can be made aware of the mapping schema. Can VS2005 provide intellisense over the +values+ that would appear in the document? A typical value might be the name of a corresponding member in a class, or even a class name itself.

    Lastly, partial types is the typical answer for the desire to have external and/or generated files.

  • Anonymous
    September 19, 2005
    I don't have a strong opinion one way or the other at the moment -- I'm still getting used to the possibilities in the brave new world of LINQ. but I note that the distinction between attributes (internal) and mapping relations (external) boils down to two patterns: internal mappings are essentially driven by the database, while external mappings allow (to a certain extent) both the code and the database to vary independently.

    internal mappings make the most sense to me when the code is written as support for the database. usually this happens in legacy systems, where the database exists a priori and is maintained by a cadre of DBAs who have more important things to worry about than your little application. in this world, the database is forever, and your application is only there to support it. attributes are a perfect solution here, since the database is only going to change slowly, if at all, but your code may well have to do complex things to get its job done.

    when the database "grows up" alongside the code, though, there's no clear driver. some days the code will change rapidly, and other days the database will change. occasionally, either before or after deployment, the database may be completely replaced. in this world, it's important to decouple both sides, and an external mapping is a good choice.

    the complex scenario that comes to mind is the case where several pieces of code are brokering data among several databases at once, and each database (and perhaps each code assembly) is owned by a different entity (perhaps the databases are in different departments, perhaps they're in different companies). in this world, external mappings are better, since they can be shared, but they seem brittle. it's easy in this scenario for changes to get out of sync, even in a carefully-controlled development environment (which we don't always have).

    this scenario starts to sound like the web services problem, with producers and consumers having to negotiate their schemata in order to communicate. I don't have a grand solution, but I figured it was worth mentioning the scenario.

  • Anonymous
    September 19, 2005
    Gentle.NET use attributes and is able to work with many different DB providers. Try it out. I have just used it for a commercial produkt and I was very pleased with it.

  • Anonymous
    September 20, 2005
    Hi, I posted a fairly long comment yesterday and it hasn't shown up. Any particular reason for that?

  • Anonymous
    September 20, 2005
    The comment has been removed

  • Anonymous
    September 20, 2005
    There is a third approach to mapping which is better then attributes or xml. We used it in our O/RM DataBlock (see www.voidsoft.ro). That's mapping directly thru code (using class inheritance). The advantages are speed (its much faster because you don't have the reflection overhead of attribute mapping) and also you don't have to cache the mapping information.
    Also you mention "easy access to mapping metadata without additional APIs". That's not true because with attributes you still have to write reflection code to get the mapping information.

  • Anonymous
    September 21, 2005
    My team is working on an ORMapper similar to DLINQ today. We chose an external xml based metadata file because we must support customer driven customization (adding a column to a table). We generate strong type objects from the metadata file. These STOs wrap the ORMapper machinery. If a customer adds a db column, we regenerate the STOs with a new property that maps to the new db column. We could not do this if the metadata were built into the STO.

    Regards,
    Dave

  • Anonymous
    September 22, 2005
    The comment has been removed

  • Anonymous
    September 22, 2005
    Hello Dinesh,

    I would very much appreciate an external-mapping file. It provides a natural border between the business logic and the database domain. Much in the same as the app.config file can be used to configure external connections for an application.

    The other reason to stick with XML files (or at least support them) is that they can be generated and parsed a lot easier than code.

    Why not support both of them? I was reading the introduction to the Windows Workflow Foundation (found at: http://www.msdn.microsoft.com/windowsvista/building/workflow/default.aspx?pull=/library/en-us/dnlong/html/WWFIntro.asp) and all tough they have a much more complicated scenario that includes more then just 'simple' attribute mapping and they share this view:

    "Why provide this markup-based option for defining workflows? One reason is that some developers prefer to work in this style, at least for certain kinds of applications. Another reason is that many tool builders find it easier to create tools that generate and parse XML rather than generating and parsing code. In fact, Windows Workflow Foundation's Workflow Designer generates XML, so developers can always see the XML version of workflows created using this tool. A workflow can be built from any combination of Workflow Designer output, developer-written code, and XML, and however it's created, it's ultimately compiled into a standard .NET assembly."

    Keep up the good work!

    Kind regards,

    Ernst Naezer.


  • Anonymous
    September 23, 2005
    In my book, advantage #3 for external mapping is the big one. Does anyone in their right mind think that hard coding physical table names in the assembly is a good thing? An external mapping that overrides the attributes might be a fair middle road but overall I believe external mappings are the correct choice. Another advantage is the ability to store query definitions in the mapping file. Intellisense for LINQ queries defined in the mapping file would be great!

  • Anonymous
    September 26, 2005
    I think you should do what they did with EJB 3.0 Persistence and that is to support both. Personally, I would probably prefer to use attributes. However, I think point #1 under Advantage external mapping is important, so, I think XML mapping files should be supported as well. I think it should be left to the developer to choose which option they prefer.

  • Anonymous
    October 13, 2005
    Just as a note. For the design-time scenario, DLINQ already has a mapping file. The SqlMetal tool that generates source also reads and writes an XML file with mapping information in it. It's just not currently used at runtime. Design-time tools are expected to use this file.

  • Anonymous
    November 05, 2005
    My vote is for Attributes for a number of reasons mostly discussed in the comments already. One benefit that I don’t think has been discussed is that using attributes allows for user extensibility. Rather than having a fixed implementation bound to xml, it you allowed these attributes to be inherited and extended then a heap of magic is possible.

    The most obvious is adding functionality for the attributes to get their mapping values from an XML file or any other data source for that matter. Which makes the XML or attributes discussion go away too.

  • Anonymous
    February 23, 2006
    The comment has been removed

  • Anonymous
    April 10, 2006
    The principal of "Separation of Concerns" suggests the virtue of external mapping files over source-code attributes.  This and also an in-code API to configure mappings (as I think Marius is suggesting) allow for many interesting design approaches so supporting all these options would be a beautiful thing and should be easy enough to do.  (Attribute support is already there and won't go away no doubt.)

  • Anonymous
    June 29, 2006
    I dont't know how LINQ works under the hood, but why not use an XML file or config section that has the relevant information that merely Overrides or creates attributes, the handling of which is done via custom type descriptors.

    Maybe the runtime is just too slow to depend on reflection?  Who cares, use shadow copy to gen the "strong" attribute based model at runtime.

    It's easy enough to create the build steps for the XML to accomodate both scenarios obviously, where you gen defaults at compile and allow only certain changes at runtime.

    This brings up a language request.  I want .h files in C#, sort of.  Just like we have partial classes, I want partial properties so that I can put all my attributes in one place.  If I can put all my declarations in one place that allows attributes, it also allows me to very easily generate a lot of code that adheres to templatable patterns without restricting myself to something like creating a DSM package.

  • Anonymous
    August 27, 2006
    Hi,

    I have written a small project about LINQ and DLinq. This might an interesting read for some of you guys.

  • Anonymous
    May 08, 2007
    Application server that I work with interacts will different databases providing common set of services such querying, caching and user defined entity types. Essentially we have set common tables for per instance of our product and on top of this we provide ability to define custom entity types which are translated/mapped into tables. At present we use our own Object/Relational translation layer but we would like to use LINQ. Now having attribute based mapping will work for built-in types of our product but we will have to use external mapping for custom types and perhaps dynamically generate C# classes first and then update the XML map. Question: How changes to external map file are handled at runtime? i.e. once DataContext is initialized from the external map.

  • Anonymous
    June 16, 2009
    PingBack from http://fixmycrediteasily.info/story.php?id=2740