tags:

views:

33

answers:

1

I have a class that needs a property set inside a LINQ-to-SQL query. My first attempt was to have a "setter" method that would return the object instance and could be used in my select, like this:

public partial class Foo
{
    public DateTime RetrievalTime { get; set; }

    public Foo SetRetrievalTimeAndReturnSelf ( DateTime value )
    {
        RetrievalTime = value;
        return this;
    }
}

....

from foo in DataContext.GetTable<Foo> select foo.SetRetrievalTimeAndReturnSelf();

Unfortunately, such a query throws an exception like this: "System.NotSupportedException: Method 'Foo.SetRetrievalTime(System.DateTime)' has no supported translation to SQL".

Is there any alternative to converting the result to a list and iterating over it? The query is used in a custom "Get" method that wraps the DataContext.GetTable method, so will be used as the base for many other queries. Immediately converting a potentially-large result set to a list would not be optimal.

UPDATE

Here's a better example of what I'm trying to do, updated with Jason's proposed solution:

protected IQueryable<T> Get<T>() where T : class, ISecurable
{
    // retrieve all T records and associated security records
    var query = from entity in DataContext.GetTable<T> ()
                from userEntityAccess in DataContext.GetTable<UserEntityAccess> ()
                where userEntityAccess.SysUserId == CurrentUser.Id
                    && entity.Id == userEntityAccess.EntityId
                    && userEntityAccess.EntityClassName == typeof ( T ).Name
                select new { entity, userEntityAccess };

    return query.AsEnumerable ()
        .Select ( item =>
        {
            item.entity.CanRead = item.userEntityAccess.CanRead;
            item.entity.CanWrite = item.userEntityAccess.CanWrite;
            item.entity.CanDelete = item.userEntityAccess.CanDelete;
            return item.entity;
        } ).AsQueryable ();
}

public interface ISecurable
{
    int Id { get; set; }
    bool CanRead { get; set; }
    bool CanWrite { get; set; }
    bool CanDelete { get; set; }
}

UserEntityAccess is a cross-reference table between a user and a business object record (i.e. an entity). Each record contains fields like "CanRead", "CanWrite", and "CanDelete", and determines what a specific user can do with a specific record.

ISecurable is a marker interface that must be implemented by any LINQ-to-SQL domain class that needs to use this secured Get method.

+1  A: 
var projection = DataContext.GetTable<Foo>
                            .AsEnumerable()
                            .Select(f => f.SetRetrievalTimeAndReturnSelf());

This will then perform the invocation of SetRetrievalTimeAndReturnSelf for each instance of Foo in DataContext.GetTable<Foo> when the IEnumerable<Foo> projection is iterated over.

What do you need to know the time that object was yanked of the database for? That's potentially smelly.

Jason
Getting the "Retrieval" time is just an example. I'm actually going to be calculating setting CanRead/CanWrite properties on the object based on another record in the query. I'll add this code to my original question. I'll also try out your solution and post the result.
MikeWyatt