Linq查询使用不同的数据源加入对象?

时间:2010-10-17 17:44:01

标签: c# asp.net-mvc linq subsonic subsonic3

我正在尝试连接两个对象,第一个是在Helper和第二个(Subsonic)数据库对象中定义的(静态)本地对象。

以下是来自我的存储库的违规摘录,除非有要求,否则我不会为你提供模型和帮助。

public IQueryable GetData(string DataType)         {

        IQueryable<DatabaseObject> datalist = (
            from t in db.All<DatabaseObject>()
            join e in WebHelpers.LocalList.AsQueryable<LocalObject>()
            on t.Type equals e.Type
            orderby t.DateOccurred descending
            select t
        ).Where(e => e.Category == TransType);

        return datalist;
    }

我意识到,通过将此表放入数据库,我可以让我的生活变得更轻松1000次,而对于下一个版本,我可能会很好地做到这一点。但有没有办法实现我想做的事情?我认为这是(a)我没有返回正确的数据类型,因为视图模型期望IQueryable或(b)Subsonic导致问题。

2 个答案:

答案 0 :(得分:2)

我担心SubSonic不支持这种交叉引用(至少我上次没试过)。

你可以解决这个问题,只使用SubSonic从数据库中检索必要的数据,然后在正常的C#Linq-to-Objects中进行加入:

public IQueryable GetData(string DataType)
{
    // Get a list of the types we need
    var requiredTypes = WebHelpers.LocalList.Select(l => l.Type)
                                  .Distinct().ToArray();

    // Retrieve all the relevant rows from the database
    var dbData = db.All<DatabaseObject>()
                                  .Where(d => requiredTypes.Contains(d.Type))
                                  .ToArray();

    // Do the join locally
    return (
        from t in dbData
        join e in WebHelpers.LocalList
        on t.Type equals e.Type
        orderby t.DateOccurred descending
        select t
    ).Where(e => e.Category == TransType);
}

(顺便说一下,如果将.Where()移到orderby之上,你可能会获得更好的性能,因为那时排序的次数就更少了。也许你甚至可以把它包含在数据库查询中(检索dbData的那个。)我无法说清楚,因为你的代码引起了混乱,因为它引用了你未在任何地方声明过的TransType,并且该方法有一个参数DataType在任何地方都没有使用,并且您使用te不一致。)

答案 1 :(得分:1)

我的最终解决方案是重新组织where子句,以确保select只返回正确的数据类型(IQueryable)。在不重新组织where子句的情况下,尽管指定了 select t ,但仍然会通过对象传递连接数据。

public IQueryable GetData(string DataType)
{

     IQueryable<DatabaseObject> dbData = (
        from t in db.All<DatabaseObject>().Where(e => e.Category == TransType)
        join e in WebHelpers.LocalList
        on t.Type equals e.Type
        orderby t.DateOccurred descending
        select t
    ); 

    return dbData;
}