var items = from c in contacts
select new ListItem
{
Value = c.ContactId, //Cannot implicitly convert type 'int' (ContactId) to 'string' (Value).
Text = c.Name
};
var items = from c in contacts
select new ListItem
{
Value = c.ContactId.ToString(), //Throws exception: ToString is not supported in linq to entities.
Text = c.Name
};
とにかくこれを達成できますか? VB.NETでは、最初のスニペットを使用しても問題ありません。VBは柔軟で、C#の厳密さに慣れることができません!!!
EF v4では、 SqlFunctions.StringConvert
を使用できます。 intにはオーバーロードがないため、doubleまたはdecimalにキャストする必要があります。コードは最終的に次のようになります。
var items = from c in contacts
select new ListItem
{
Value = SqlFunctions.StringConvert((double)c.ContactId).Trim(),
Text = c.Name
};
クエリから整数を文字列に変換することで、同様の問題を解決しました。これは、クエリをオブジェクトに入れることで実現できます。
var items = from c in contacts
select new
{
Value = c.ContactId,
Text = c.Name
};
var itemList = new SelectList();
foreach (var item in items)
{
itemList.Add(new SelectListItem{ Value = item.ContactId, Text = item.Name });
}
LinqToObjectを使用します。contacts.AsEnumerable()
var items = from c in contacts.AsEnumerable()
select new ListItem
{
Value = c.ContactId.ToString(),
Text = c.Name
};
SqlFunctions.StringConvertは機能しますが、面倒であり、ほとんどの場合、SQL側で文字列変換を実行する必要はほとんどありません。
文字列操作を行う場合は、最初にlinq-to-entitiesでクエリを実行し、次にlinq-to-objectsのスティングを操作します。この例では、連絡先の氏名と、2つの整数列(ContactIDとLocationID)の文字列連結であるContactLocationKeyを含むデータのセットを取得します。
// perform the linq-to-entities query, query execution is triggered by ToArray()
var data =
(from c in Context.Contacts
select new {
c.ContactID,
c.FullName,
c.LocationID
}).ToArray();
// at this point, the database has been called and we are working in
// linq-to-objects where ToString() is supported
// Key2 is an extra example that wouldn't work in linq-to-entities
var data2 =
(from c in data
select new {
c.FullName,
ContactLocationKey = c.ContactID.ToString() + "." + c.LocationID.ToString(),
Key2 = string.Join(".", c.ContactID.ToString(), c.LocationID.ToString())
}).ToArray();
さて、2つの匿名選択を記述する必要があるのは面倒になりますが、L2Eでサポートされていない文字列(およびその他の)機能を実行できる利便性を上回っていると思います。また、この方法を使用するとパフォーマンスが低下する可能性があることに注意してください。
public static IEnumerable<SelectListItem> GetCustomerList()
{
using (SiteDataContext db = new SiteDataContext())
{
var list = from l in db.Customers.AsEnumerable()
orderby l.CompanyName
select new SelectListItem { Value = l.CustomerID.ToString(), Text = l.CompanyName };
return list.ToList();
}
}
var selectList = db.NewsClasses.ToList<NewsClass>().Select(a => new SelectListItem({
Text = a.ClassName,
Value = a.ClassId.ToString()
});
まず、オブジェクトに変換してから、toString()が正しくなります。
Brian Cauthonの答えは素晴らしいです!ほんの少しの更新、EF 6では、クラスは別の名前空間に移動しました。したがって、EF 6の前に、以下を含める必要があります。
System.Data.Objects.SqlClient
EF 6に更新する場合、または単にこのバージョンを使用している場合は、以下を含めます。
System.Data.Entity.SqlServer
EF6に誤った名前空間を含めると、コードは正常にコンパイルされますが、実行時エラーがスローされます。このメモが混乱を避けるのに役立つことを願っています。
あなたの「連絡先」が一般的なリストとして機能している場合、次のコードがうまく機能することを望みます。
var items = contact.Distinct().OrderBy(c => c.Name)
.Select( c => new ListItem
{
Value = c.ContactId.ToString(),
Text = c.Name
});
ありがとう。
MVC 2アプリをMVC 3に変換しているときにこの同じ問題に遭遇し、この問題に対する別の(クリーンな)ソリューションを提供するために、自分がやったことを投稿したい...
IEnumerable<SelectListItem> producers = new SelectList(Services.GetProducers(),
"ID", "Name", model.ProducerID);
GetProducers()は、単にProducersのエンティティコレクションを返します。追伸SqlFunctions.StringConvertは機能しませんでした。
もう1つのソリューション:
c.ContactId + ""
空の文字列を追加するだけで、文字列に変換されます。
エンティティフレームワークを使用し、唯一のintを受け入れられるようにしたい場合は、これをlinqクエリで使用できます。
var items = from c in contacts
select new ListItem
{
Value = (int)ContractId
Text = c.Name
};
(int)を使用すると値がintにキャストされるため、文字列をintに変換する必要がなく、目的の結果が得られるため、機能します。
これは私のプロジェクトで私のために働いた
MySqlを使用すると、SqlFunctions.StringConvert
は機能しませんでした。プロジェクトの20以上の場所でSelectListItem
を使用しているため、20以上のLINQステートメントをゆがめることなく機能するソリューションが必要でした。私の解決策は、整数セッターを提供するためにSelectedListItem
をサブクラス化することで、型変換をLINQから遠ざけます。明らかに、このソリューションは一般化するのが難しいですが、私の特定のプロジェクトにとっては非常に役に立ちました。
使用するには、次のタイプを作成し、SelectedListItem
の代わりにLINQクエリで使用し、Valueの代わりにIntValueを使用します。
public class BtoSelectedListItem : SelectListItem
{
public int IntValue
{
get { return string.IsNullOrEmpty(Value) ? 0 : int.Parse(Value); }
set { Value = value.ToString(); }
}
}