web-dev-qa-db-ja.com

Linqからエンティティへのintから文字列への変換に関する問題

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#の厳密さに慣れることができません!!!

199
Shimmy

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
            };
309
Brian Cauthon

クエリから整数を文字列に変換することで、同様の問題を解決しました。これは、クエリをオブジェクトに入れることで実現できます。

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 });
}
12
Jente Rosseel

LinqToObjectを使用します。contacts.AsEnumerable()

var items = from c in contacts.AsEnumerable()
            select new ListItem
            {
                Value = c.ContactId.ToString(),
                Text = c.Name
            };
9
Mohammadreza

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でサポートされていない文字列(およびその他の)機能を実行できる利便性を上回っていると思います。また、この方法を使用するとパフォーマンスが低下する可能性があることに注意してください。

5
Walter Stabosz
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();
            }
        }
4
Nestor
var selectList = db.NewsClasses.ToList<NewsClass>().Select(a => new SelectListItem({
    Text = a.ClassName,
    Value = a.ClassId.ToString()
});

まず、オブジェクトに変換してから、toString()が正しくなります。

3
phil hong

Brian Cauthonの答えは素晴らしいです!ほんの少しの更新、EF 6では、クラスは別の名前空間に移動しました。したがって、EF 6の前に、以下を含める必要があります。

System.Data.Objects.SqlClient

EF 6に更新する場合、または単にこのバージョンを使用している場合は、以下を含めます。

System.Data.Entity.SqlServer

EF6に誤った名前空間を含めると、コードは正常にコンパイルされますが、実行時エラーがスローされます。このメモが混乱を避けるのに役立つことを願っています。

3
Leo

あなたの「連絡先」が一般的なリストとして機能している場合、次のコードがうまく機能することを望みます。

var items = contact.Distinct().OrderBy(c => c.Name)
                              .Select( c => new ListItem
                              {
                                Value = c.ContactId.ToString(),
                                Text = c.Name
                              });

ありがとう。

2
Nawaz

MVC 2アプリをMVC 3に変換しているときにこの同じ問題に遭遇し、この問題に対する別の(クリーンな)ソリューションを提供するために、自分がやったことを投稿したい...

IEnumerable<SelectListItem> producers = new SelectList(Services.GetProducers(),
    "ID", "Name", model.ProducerID);

GetProducers()は、単にProducersのエンティティコレクションを返します。追伸SqlFunctions.StringConvertは機能しませんでした。

2
BarryC

もう1つのソリューション:

c.ContactId + ""

空の文字列を追加するだけで、文字列に変換されます。

1
Igor Valikovsky

エンティティフレームワークを使用し、唯一のintを受け入れられるようにしたい場合は、これをlinqクエリで使用できます。

var items = from c in contacts
        select new ListItem
        {
            Value = (int)ContractId 
            Text = c.Name
        };

(int)を使用すると値がintにキャストされるため、文字列をintに変換する必要がなく、目的の結果が得られるため、機能します。

これは私のプロジェクトで私のために働いた

1
Saurabh Solanki

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(); }
    }
}
1
raider33