Эта ошибка исходит от 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 для лиц использует отложенное выполнение SQL, а это означает, что ваш запрос LINQ не попал в базе данных, пока не перебрать IQueryable
с использованием Еогеаспа, или вызвать метод, как ToList
или ToArray
на IQueryable
. Вы можете использовать любой код в выражении предиката LINQ, но он не будет работать во время выполнения, если LINQ to Entities не сможет понять, как его перевести в SQL. Ваш код не работает, поскольку LINQ to Entities не может понять, как конкатенация CustomerName, вашей пользовательской строки и PhoneNumber во время выполнения SQL-запроса. Вышеупомянутое работает, потому что оно сначала получает данные из базы данных, а затем конкатенация строк в памяти.
Update
Чтобы расширить на лучшее решение, которое @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
}
Затем вы должны иметь возможность запрашивать из данных, как это:
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)
});
Возможно, попробуйте 'cc.Phone.ToString()'? –
base {System.SystemException} = {«LINQ to Entities не распознает метод« Система ».String ToString() ', и этот метод не может быть переведен в выражение хранилища. "} – Preston
Почему нет cc.Phone строки? Это, конечно, не int64 .... [Какой правильный способ представления телефона номера?] (http://stackoverflow.com/a/3483166/1808494) – Aron