Why can't I use a dictionary with Entity Framework
-
14-04-2021 - |
문제
Dictionary<int, string> D = new Dictionary<int, string>();
D.Add(0, "Insert");
D.Add(1, "Update");
D.Add(2, "Delete");
using (SerasMacEntity SME = new SerasMacEntity())
{
var SQL = (from p in SME.tbl_admin_islem
let testx = D.Where(x => x.Key == p.islem).Select(x => x.Value).FirstOrDefault()
orderby p.tarih descending
select new
{
p.id,
p.islem,
p.tarih
});
Store1.DataSource = SQL;
Store1.DataBind();
}
Its giving this error;
'System.Collections.Generic.KeyValuePair`2' and Only primitive types ('such as Int32, String, and Guid')
I use this method in Linq but I can't use Entity.
public class table
{
public int ID { get; set; }
public string Adi { get; set; }
public int IslemID { get; set; }
public table() { }
public table(int _ID, string _Adi, int _IslemID)
{
_ID = ID;
_Adi = Adi;
_IslemID = IslemID;
}
}
public List<table> table_list = new List<table>(new table[]
{
new table{ID=1,Adi="A1",IslemID=0},
new table{ID=2,Adi="A2",IslemID=1},
new table{ID=3,Adi="A3",IslemID=2},
new table{ID=4,Adi="A4",IslemID=1},
new table{ID=5,Adi="A5",IslemID=0},
new table{ID=6,Adi="A6",IslemID=2},
new table{ID=7,Adi="A7",IslemID=0},
new table{ID=8,Adi="A8",IslemID=1},
new table{ID=9,Adi="A9",IslemID=3}
});
public Dictionary<int, string> option_dictionary = new Dictionary<int,string>()
{
{0, "OK"},
{1, "NO"},
{2, "YA"},
{3, "OH"}
};
public void TestL()
{
string b = option_dictionary.Where(x => x.Key == 1).Select(x =>x.Value).First();
var SQL = (from p in table_list
let test = option_dictionary.Where(x => x.Key == p.IslemID).Select(x => x.Value).First()
select new
{
p.ID,
p.Adi,
test
}
);
}
This method is working in Linq. Its not working in Entity.
Thanks for your help.
해결책 2
I solve it this method;
var SQL = (from p in SME.tbl_admin_islem
orderby p.tarih descending
select new
{
p.id,
p.islem,
p.tarih
}).AsEnumerable().Select(s => new
{
s.id,
s.islem,
s.tarih,
testx = D.Where(x => x.Key == s.islem).Select(x => x.Value).FirstOrDefault()
});
or try this
var SQL = (from p in SME.tbl_admin_islem.AsEnumerable()
orderby p.tarih descending
select p).Select(s => new
{
s.id,
s.islem,
s.tarih,
testx = D.Where(x => x.Key == s.islem).Select(x => x.Value).FirstOrDefault()
});
I was convert my entity AsEnumerable() and then apply again Lambda query.
다른 팁
LINQ is not the same as LINQ. Your working example uses a data structure in memory, namely List<table> table_list
or more generally an IEnumerable<T>
. Using the LINQ extension methods of IEnumerable<T>
is called LINQ to Objects.
When you apply LINQ to an ObjectSet<T>
or DbSet<T>
of Entity Framework you are using the LINQ extension methods of IQueryable<T>
. In this case you are using LINQ to Entities. They have the same name and you can write the same LINQ expressions like with LINQ to Objects and your code will compile fine.
But the big difference is that a LINQ to Entities query is not executed in memory (like LINQ to Objects) but it has to be translated into SQL to be executed in the database.
If your query is not translatable into SQL or the translation is not supported you get a runtime exception. In your specific case you have a complex in memory data structure - your dictionary - which cannot be used in a SQL query.
You have to rewrite your query to solve the problem. I would use the dictionary after you have executed the query, for example this way:
public class Helper
{
public int id { get; set; }
public int islem { get; set; }
public string textx { get; set; }
// ...
}
using (SerasMacEntity SME = new SerasMacEntity())
{
var SQL = (from p in SME.tbl_admin_islem
orderby p.tarih descending
select new Helper
{
id = p.id,
islem = p.islem,
//...
});
var list = SQL.ToList(); // excutes query in DB, rest happens in memory
foreach (var item in list)
{
item.testx = D.Where(x => x.Key == item.islem)
.Select(x => x.Value)
.FirstOrDefault();
}
Store1.DataSource = list;
Store1.DataBind();
}