tags:

views:

196

answers:

4

If I have something like:

var query = from children in _data.Children
    where children.ChildId == childId
    select new CustomModel.MyChild
    {
     ChildId = children.ChildId,
     Name = children.ChildName
    };

return query.FirstOrDefault();

Where I want the resultant object to be my custom model.

Can I handle the custom model instantiation in a different method, which could be reused if I had multiple linq queries that all generated a custom child model?

For example,

var query = from children in _data.Children
    where children.ChildId == childId
    select CreateMyCustomChild([param ??]);

return query.FirstOrDefault();

This may well be impossible, I don't know, but what would the method signature be like if it is possible?

I'm only thinking reuse for when multiple linq queries contain duplicate object initialisation code.

Thanks

A: 

If you wanted you could write "select 1" or in your case "CreateMyCustomChild(children)" since "children" is containing all your info. In your case you aren't adding a lot of info to "children", so why not "select children"?

In other words, just try it out. The return type of your value will determine over which type your LINQ enumerates.

flq
+1  A: 

It really depends on what version of LINQ you're using. If you're using LINQ to SQL, I don't believe you can call arbitrary methods in the query. The query translator wouldn't know what to do with the method call

If you're using LINQ to Objects, you're absolutely fine to do it, like this:

var query = from children in _data.Children
    where children.ChildId == childId
    select CreateMyCustomChild(children)

return query.FirstOrDefault();

// Elsewhere

public CustomModel.MyChild CreateMyCustomChild(OtherChild child)
{
    return new CustomModel.MyChild
    {
        ChildId = child.ChildId,
        Name = child.ChildName
    };
}

(Side note: I'd call the range variable in the query "child" rather than "children" as at any one time it only represents a single child.)

Jon Skeet
@Jon - thanks. Sadly, it's linqtosql. Also get the point about singular child.
Tim Peel
A: 

Suppose you had a method that did the transform for you.

public static class Conversions
{
  public static CustomModel.MyChild ToCustomModel(this DataModel.MyChild source)
  {
    return new CustomModel.MyChild()
    {
      ChildId = source.ChildId,
      Name = source.ChildName
    }
  }
}

You can use such a method to do the conversion of a single item.

DataModel.MyChild myResult = getResult();
CustomModel.MyChild myConvertedResult = myResult.ToCustomModel()

Such a method can also be used in a Enumerable.Select method call.

IEnumerable<DataModel.MyChild> myQueriedResults = getResult();
IEnumerable<CustomModel.MyChild> myConvertedResults =
  myQueryiedResults.Select(c => c.ToCustomModel());
David B
A: 

While you can do with expressions, I don't think it is worth the hassle. Instead I suggest you define an extension method like:

IQueryable<CustomModel.MyChild> ToModel(this IQueryable<Child> childs)
{
    return childs.Select( c=>
       select new CustomModel.MyChild
       {
           ChildId = children.ChildId,
           Name = children.ChildName
       }    
    );
}

You can then call:

return _data.Children
     .Where(c=>c.ChildId == childId)
     .ToModel()
     .FirstOrDefault();
eglasius