【问题标题】:Changing selected objects inside a query更改查询中的选定对象
【发布时间】:2010-02-02 17:43:30
【问题描述】:

我有一个需要在 LINQ-to-SQL 查询中设置属性的类。我的第一次尝试是有一个“setter”方法,它可以返回对象实例并可以在我的选择中使用,如下所示:

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();

不幸的是,这样的查询会引发如下异常:“System.NotSupportedException: Method 'Foo.SetRetrievalTime(System.DateTime)' has no supported translation to SQL”。

除了将结果转换为列表并对其进行迭代之外,还有其他方法吗?该查询用于包装 DataContext.GetTable 方法的自定义“Get”方法,因此将用作许多其他查询的基础。立即将可能很大的结果集转换为列表并不是最优的。

更新

这是我正在尝试做的一个更好的例子,更新了 Jason 提出的解决方案:

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 是用户和业务对象记录(即实体)之间的交叉引用表。每条记录都包含“CanRead”、“CanWrite”和“CanDelete”等字段,并确定特定用户可以对特定记录执行什么操作。

ISecurable 是一个标记接口,必须由任何需要使用此安全 Get 方法的 LINQ-to-SQL 域类实现。

【问题讨论】:

    标签: c# linq-to-sql


    【解决方案1】:
    var projection = DataContext.GetTable<Foo>
                                .AsEnumerable()
                                .Select(f => f.SetRetrievalTimeAndReturnSelf());
    

    IEnumerable&lt;Foo&gt; projection 被迭代时,这将为DataContext.GetTable&lt;Foo&gt; 中的每个Foo 实例执行SetRetrievalTimeAndReturnSelf 调用。

    您需要知道从数据库中拉出该对象的时间是什么?那可能很臭。

    【讨论】:

    • 获取“检索”时间只是一个例子。我实际上将根据查询中的另一条记录来计算设置对象的 CanRead/CanWrite 属性。我会将此代码添加到我原来的问题中。我也会尝试您的解决方案并发布结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 2019-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    相关资源
    最近更新 更多