Jarrod Dixon
Jarrod Dixon

Reputation: 15807

Can LINQ to SQL fill non-ColumnAttribute-marked properties when using DataContext.ExecuteQuery?

Given this table:

CREATE TABLE [Comments]
(
  [Id] [int] IDENTITY(1, 1) NOT NULL, 
  [Text] [nvarchar](600) NOT NULL
)

With this model class:

[Table(Name="Comments")]
public class Comment
{
    [Column(AutoSync = AutoSync.OnInsert, DbType = "Int NOT NULL IDENTITY", IsPrimaryKey = true, IsDbGenerated = true)]
    public int Id { get; set; }

    [Column(DbType = "NVarChar(600) NOT NULL", CanBeNull = false)]
    public string Text { get; set; }

    public string ArbitraryText { get; set; }
}

Is it possible for a DataContext to fill the ArbitraryText property when using the ExecuteQuery method:

var comments = db.ExecuteQuery<Comment>("select Id, [Text], 'hello' [ArbitraryText] from Comments");

It seems that the entity mapping algorithm ignores any property not marked with ColumnAttribute, but is there another way of doing this?

I'd prefer not having to do the mapping myself, but this looks like my only option.


Edit: What's annoying is that the DataContext.ExecuteQuery function will fill a POCO object from a query:

public class PlainOldCSharpObject
{
    public int Id { get; set; }
    public string Text { get; set; }
    public string ArbitraryText { get; set; }
}
...
// DataContext correctly fills these objects
var pocos = db.ExecuteQuery<PlainOldCSharpObject>("select Id, [Text]...

So my current solution is to have an inner class on my LINQ-mapped object that holds the extra data my aggregate query returns. This is sub-optimal, as some properties are duplicated (for example, Id and Text).

Upvotes: 7

Views: 1722

Answers (1)

Marc Gravell
Marc Gravell

Reputation: 1064204

Not as far as I know. You could probably do some grungy things to marry data from a UDF, perhaps - but other than that, it is going to want to be able to map the columns.

(where the UDF just returns the arbitrary text and the comment-id)

var qry = from row in db.SomeUdfQuery(someArgs)
          join comment in db.Comments
          on row.Id equals comment.Id
          select new {Comment = comment, row.ArbitraryText};

var comments = new List<Comment>();
foreach(var record in qry) {
    record.Comment.ArbitraryText = record.ArbitraryText;
    comments.Add(record.Comment);
}
return comments;

Alternatively - A while I wrote a few variants on ExecuteQuery that might be useful if you need to use this approach for lots of different things... Personally, I'd probably try to side-step the issue first, though.

Upvotes: 2

Related Questions