views:

380

answers:

1

I've been using LINQ extensively in my recent projects, however, I have not been able to find a way of dealing with objects that doesn't either seem sloppy or impractical.

I'll also note that I primarily work with ASP.net.

I hate the idea of exposing the my data context or LINQ returned types to my UI code. I prefer finer grained control over my business objects, and it also seems too tightly coupled to the db to be good practice.

Here are the approaches I've tried ..


Project items into a custom class

dc.TableName.Select(λ => new MyCustomClass(λ.ID, λ.Name, λ.Monkey)).ToList();

This obviously tends to result in a lot of wireup code for creating, updating etc...


Creating a wrapper around returned object

public class MyCustomClass
{
      LinqClassName _core;

      Internal MyCustomClass(LINQClassName blah)
      {
          _core = blah;
      }

      int ID {get { return _core.ID;}}
      string Name { get {return _core.Name;} set {_core.Name = value;} }
}

...
dc.TableName.Select(λ => new MyCustomClass(λ)).ToList();

Seems to work pretty well but reattaching for updates seems to be nigh impossible somewhat defeating the purpose.

I also tend to like using LINQ Queries for transformations and such through my code and I'm worried about a speed hit with this method, although I haven't tried it with large enough sets to confirm yet.


Creating a wrapper around returned object while persisting data context

public class MyCustomClass
{
   LinqClassName _core;
   MyDataContext _dc;
    ...
}

Persisting the data context within my object greatly simplifies updates but seems like a lot of overhead especially when utilizing session state.

A quick Note: I know the usage of λ is not mathematically correct here - I tend to use it for my bound variable because it stands out visually, and in most lambda statements it is the transformation that is important not the variable - not sure if that makes any sense but blah

Sorry for the extremely long question. Thanks in advance for your input and Happy New Years!

+1  A: 

I create "Map" extension functions on the tables returning from the LINQ queries. The Map function returns a plain old CLR object. For example:

public static MyClrObject Map(this MyLinqObject o)
        {
            MyClrObject myObject = new MyClrObject()
            {
                stringValue = o.String,
                secondValue = o.Second
            };
            return myObject;
        }

You can then add the Map function to the select list in the LINQ query and have LINQ return the CLR Object like:

return (from t in dc.MyLinqObject
            select t.Map()).FirstOrDefault();

If you are returning a list, you can use the ToList to get a List<> back. If you prefer to create your own list types, you need to do two things. First, create a constructor that takes an IEnumerable<> of the underlying type as it's one argument. That constructor should copy the items from the IEnumerable<> collection. Second, create a static extension method to call that constructor from the LINQ query:

        public static MyObjectList ToMyObjectList(this IEnumerable<MyObjectList> collection)
    {
        return new MyObjectList (collection);
    }

Once these methods are created, they kind of hide in the background. They don't clutter up the LINQ queries and they don't limit what operations you can perform in teh query.

This blog entry has a more thorough explanation.

Jeff Siver