2012-08-17 98 views
0

我有一个lambda expression可以从我的表中获取多个记录。该查询的返回类型应该是什么?

这里是表达

public sys_Log_Deposits_Interest_Master GetDepositsPendingRecord(string glCode, int fromDateID) 
     { 
      using (var db = new DataClasses1DataContext()) 
      { 
       var deposit = db.sys_Log_Deposits_Interest_Masters.Where(deposits => deposits.cGLCode.Equals(glCode) && deposits.nFromDateID.Equals(fromDateID)); 
       return deposit; 
      } 
     } 

我得到一个错误Cannot implicitly convert type IQueryable To Table Object

我想将表格对象返回到我的Update method,它将更新结果的一些文件。

这里是我的更新方法

public void UpdatePendingRecords(string glCode, int fromDateID) 
     { 
      using (var db = new DataClasses1DataContext()) 
      { 

       var deposit = GetDepositsPendingRecord(glCode, fromDateID); 

       foreach (var pending in deposit) 
       { 
        pending.cAuthorizedStatus = "Authorized"; 
        pending.dAuthorizedOn = DateTime.Now; 
        pending.cAuthorizedBy = HttpContext.Current.User.Identity.Name; 

       } 
} 
} 

目前我无法得到它的工作。

任何人都可以帮助我解决这个问题吗?

任何帮助,非常感谢。

+0

使用第一个或FirstOrDefault扩展方法。例如,返回deposit.First(); – 2012-08-17 08:11:25

回答

2

这是一个IQueryable<T>其中T是任何类型sys_Log_Deposits_Interest_Masters是一个表。例如IQueryable<Log_Deposits_Interest_Master>

请注意,sys_Log_Deposits_Interest_Masters是一个实例的表类还实现该接口。结果是一个不同的实现,它有信息知道它应该从那里得到结果,并在Where中应用过滤器。

您也将上下文置于错误的地方,因为在值被枚举的时候它不会存在。

在这种情况下,因为你要直接对结果的工作,而不是应用任何进一步的更改查询,我的方法倒是foreach通过结果和yield他们,所以它就会变成一个枚举块并且生命得到不同的处理。否则,我会通过将数据上下文传递给该方法而不是在那里创建数据上下文来确保数据上下文的存活时间更长,否则我就不会处理它(但只是在一个捏,而linq2sql人说没有处理datacontexts是安全的,这是违背良好的做法 - 你应该真的假设这样做是不安全的 - 也只是最安全的时候;你想知道什么时候是或否?我也没有。编辑:今天巧合带来了一个例子,它不安全与https://stackoverflow.com/a/12002914/400547)。

编辑举例:

最好的方法:

public IQueryable<Log_Deposits_Interest_Master> GetDepositsPendingRecord(DataClasses1DataContext db, string glCode, int fromDateID) 
{ 
    return db.sys_Log_Deposits_Interest_Masters.Where(deposits => deposits.cGLCode.Equals(glCode) && deposits.nFromDateID.Equals(fromDateID)); 
} 

public void UpdatePendingRecords(string glCode, int fromDateID) 
{ 
    using (var db = new DataClasses1DataContext()) 
    { 

    var deposit = GetDepositsPendingRecord(db, glCode, fromDateID); 

    foreach (var pending in deposit) 
    { 
     pending.cAuthorizedStatus = "Authorized"; 
     pending.dAuthorizedOn = DateTime.Now; 
     pending.cAuthorizedBy = HttpContext.Current.User.Identity.Name; 

    } 

    //presumably you want to call db.SubmitChanges() here, no? 
    } 
} 

如果你真的必须包括调用的方法中的datacontext的创作,你可以做

public IEnumerable<Log_Deposits_Interest_Master> GetDepositsPendingRecord(string glCode, int fromDateID) 
{ 
    using(var db = new DataClasses1DataContext()) 
    foreach(Log_Deposits_Interest_Master item in db.sys_Log_Deposits_Interest_Masters.Where(deposits => deposits.cGLCode.Equals(glCode) && deposits.nFromDateID.Equals(fromDateID)) 
     yield return item; 
} 

然而,这”不是个如果你想保存你所做的更改到数据库非常有用,那么你必须调用SubmitChanges()在相同的情况下,你从他们或重新绑定他们。这也意味着,如果您要在其上添加另一个Where(),或者使用Count()或其他任何可以传递到数据库的内容,那么这不会,因为我们已经打破了该点的可查询能力。

+0

你能帮我一个例子吗?谢谢你的回答。 – freebird 2012-08-17 08:19:07

+1

删除我的答案,因为这涵盖了我想说的一切,但更好:) – 2012-08-17 09:00:18

+0

@Jon Hanna感谢您的详细答案。真的很好解释。谢谢。 – freebird 2012-08-17 09:04:22

1

从我看到的db。sys_Log_Deposits_Interest_Masters表示sys_Log_Deposits_Interest_Master对象的集合。您的Where查询还会返回无法转换为单个对象的对象集合(IQueriable)。如果您确定您的Where查询返回了一个且只有一个条目,那么可以用Single或SingleOrDefault语句替换它,并使用相同的条件。如果它可以返回多个对象,但只需要第一个对象,则可以使用First或FirstOrDefault,并使用相同的条件。

+0

@EIDog我的表格将返回多个记录。感谢您的帮助。 – freebird 2012-08-17 08:21:09

0

添加.ToList()扩展,则是这样的:

var deposit = db.sys_Log_Deposits_Interest_Masters.Where(deposits => deposits.cGLCode.Equals(glCode) && deposits.nFromDateID.Equals(fromDateID)).ToList(); 
+0

如果每次只使用一个,为什么要将每个结果加载到内存中? – 2012-08-17 08:17:41

+0

调用foreach循环会将它全部加载到内存中,它只是在早些时候执行两次执行。 – hofnarwillie 2012-08-17 08:19:04

+0

调用foreach循环将一次加载到内存中,在将它作为一个单元传递之前,您将首先加载每个循环 - 这会导致大量的结果集,这可能是浪费的内存和浪费的时间。即使有一个小的结果集,当你没有特定的理由(在下一个操作之前需要知道大小,在相同的数据上做几次传递),使用'ToList()'是过早的悲观。此外,如果他们想要将更改保存回数据库,则无论如何都需要保持上下文。 – 2012-08-17 08:52:57

相关问题