此错误来自 LINQ 到实体。这是一种解决方案:
var tempCustomers =
from c in db.Customers.ToArray()
let cc = db.CustomerContacts
.FirstOrDefault(x => x.CustomerID == c.CustomerID)
select new
{
cc.CustomerContactID,
CustomerValue = string.Format("{0} 	 	 {0}",
c.CustomerName, cc.Phone)
};
以上将在尝试进行字符串连接之前访问数据库。如果这是不可接受的,请在您的问题中注明。
为什么它不起作用
LINQ to Entities 使用延迟 SQL 执行,这意味着您的 LINQ 查询将不会访问数据库,直到您使用 foreach 迭代或IQueryable
调用类似. 您可以在 LINQ 谓词表达式中使用您想要的任何代码,但如果 LINQ to Entities 无法弄清楚如何将其转换为 SQL,它将在运行时失败。您的代码失败,因为 LINQ to Entities 在运行 SQL 查询时无法弄清楚如何连接 CustomerName、您的自定义字符串和 PhoneNumber。上面的工作是因为它首先从数据库中获取数据,然后在内存中进行字符串连接。ToList
ToArray
IQueryable
更新
要扩展 @JeffMercado 击败我的更好的解决方案,您真的应该使用导航属性来加入Customer
和CustomerContacts
. 这将消除对let
子句和First
orFirstOrDefault
调用的需要:
public class Customer
{
public long CustomerID { get; set; }
public string CustomerName { get; set; }
public virtual ICollection<CustomerContact> Contacts { get; set; }
}
public class CustomerContact
{
public long CustomerContactID { get; set; }
public long CustomerID { get; set; }
public virtual Customer Owner { get; set; }
public long Phone { get; set; } // I agree this should be a string
}
然后,您应该能够像这样查询数据:
var query = db.CustomerContacts
.Include(x => x.Owner) // eager load to avoid multiple separate SQL queries
.Select(x => new {
CustomerContactID = x.CustomerContactID,
CustomerName = x.Owner.CustomerName,
Phone = x.Phone,
});
从这里,您可以使用AsEnumerable
、ToArray
或ToList
来执行查询并格式化您的特殊CustomerValue
属性。
var results = query
.ToArray() // or .AsEnumerable(), or .ToList(), all will execute the SQL query
.Select(x => new {
CustomerContactId = x.CustomerContactID,
CustomerValue = string.Format("{0} 	 	 {1}",
x.CustomerName, x.Phone)
});