C# LINQ cast int64发行版
我需要这个linq查询才能工作,但linq抱怨customercontact和电话是int64s,我还需要在第二列中进行讨论,但我担心出于同样的原因,这不起作用。如果我添加一个tostring(),它只会说linq不认识它C# LINQ cast int64发行版,c#,linq,linq-to-entities,C#,Linq,Linq To Entities,我需要这个linq查询才能工作,但linq抱怨customercontact和电话是int64s,我还需要在第二列中进行讨论,但我担心出于同样的原因,这不起作用。如果我添加一个tostring(),它只会说linq不认识它 base{System.SystemException}={“无法强制转换类型” “System.Int64”以键入“System.Object”。LINQ to实体仅支持 强制转换EDM基元或枚举类型。“} 此错误来自LINQ到实体。这里有一个解决方案: var tempC
base{System.SystemException}={“无法强制转换类型” “System.Int64”以键入“System.Object”。LINQ to实体仅支持 强制转换EDM基元或枚举类型。“}
此错误来自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
,或者调用IQueryable
上的ToList
或ToArray
。您可以在LINQ谓词表达式中使用所需的任何代码,但如果LINQ to实体无法理解如何将其转换为SQL,则在运行时将失败。您的代码失败,因为LINQ to Entities在运行SQL查询时无法确定如何连接CustomerName、自定义字符串和电话号码。上述方法之所以有效,是因为它首先从数据库获取数据,然后在内存中进行字符串连接
更新
要扩展@JeffMercado击败我的更好的解决方案,您确实应该使用导航属性来加入Customer
和CustomerContacts
。这样就不需要使用let
子句和First
或FirstOrDefault
调用:
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
}
从这里,您可以使用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)
});
查询中可以执行的操作类型在EF中是有限的,转换就是其中之一。您需要将该部分移出查询,只需获取数据,然后使用
AsEnumerable()
,这样您就可以使用LINQ to对象了。然后你可以对数据做任何你想做的事情
var query=
from c in db.Customers
let cc = c.CustomerContacts.FirstOrDefault() // better to use the navigation properties instead
select new // select the fields you need
{
cc.CustomerContactId,
c.CustomerName,
Phone = (long?)cc.Phone, // cc could potentially be null this long must also be nullable
};
var tempCustomers =
from x in query.AsEnumerable() // LINQ to Objects
select new // now you can do what you want to the data
{
x.CustomerContactId,
CustomerValue = x.CustomerName + " 	 	 " + x.Phone,
};
为了可读性,我将语句分成了几个单独的语句,但如果您愿意,可以将它们组合起来。也许可以尝试
cc.Phone.ToString()
?base{System.SystemException}={“LINQ to Entities无法识别方法'System.String ToString()'方法,并且此方法无法转换为存储表达式。”}为什么cc.Phone不是字符串?它当然不是int64…您是否尝试过Convert.ToString(c.CustomerName)
?@Preston,这显然是错误的。作为long
,诸如0014155551212
之类的数字相当于14155551212
。电话号码是字符串。这两个字符串不包含相同的信息。使用数字捕获电话号码是错误的。当我调试并尝试扩展var查询的结果时,我得到的结果是base{System.SystemException}={“转换为值类型'Int64'失败,因为具体化的值为null。结果类型的泛型参数或查询必须使用可为null的类型。”}您需要记住,通过使用FirstOrDefault()
,cc
可能是null
,因此实际上,您要选择的所有值类型都必须声明为null。我希望这是问题所在,但不是问题所在,我只是反复检查以确定,它们在两个位置都不可为空,并且在没有电话的情况下,数据库中没有记录。
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)
});
var query=
from c in db.Customers
let cc = c.CustomerContacts.FirstOrDefault() // better to use the navigation properties instead
select new // select the fields you need
{
cc.CustomerContactId,
c.CustomerName,
Phone = (long?)cc.Phone, // cc could potentially be null this long must also be nullable
};
var tempCustomers =
from x in query.AsEnumerable() // LINQ to Objects
select new // now you can do what you want to the data
{
x.CustomerContactId,
CustomerValue = x.CustomerName + " 	 	 " + x.Phone,
};