【问题标题】:Why can't I use a dictionary with Entity Framework为什么我不能在实体框架中使用字典
【发布时间】:2012-02-04 21:01:52
【问题描述】:
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();
}

它给出了这个错误;

'System.Collections.Generic.KeyValuePair`2' 和只有原始类型 ('如 Int32、String 和 Guid')

我在 Linq 中使用了这种方法,但我不能使用 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
    }
    );
}

此方法在 Linq 中有效。它在实体中不起作用。

感谢您的帮助。

【问题讨论】:

    标签: c# linq entity-framework dictionary let


    【解决方案1】:

    我用这个方法解决了;

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

    或者试试这个

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

    我正在转换我的实体 AsEnumerable(),然后再次应用 Lambda 查询。

    【讨论】:

    • 第一种方式很好。第二个,我不确定。我相信它会将完整的实体加载到内存中,然后在内存中将排序和投影应用到匿名类型中。我认为,第二种方式的效率不如第一种。
    【解决方案2】:

    LINQ 与 LINQ 不同。您的工作示例使用内存中的数据结构,即List&lt;table&gt; table_list 或更一般的IEnumerable&lt;T&gt;。使用IEnumerable&lt;T&gt; 的LINQ 扩展方法称为LINQ to Objects

    当您将 LINQ 应用到实体框架的 ObjectSet&lt;T&gt;DbSet&lt;T&gt; 时,您使用的是 IQueryable&lt;T&gt; 的 LINQ 扩展方法。在这种情况下,您使用的是 LINQ to Entities。它们具有相同的名称,您可以编写与 LINQ to Objects 相同的 LINQ 表达式,并且您的代码可以正常编译。

    但最大的区别在于 LINQ to Entities 查询不是在内存中执行(如 LINQ to Objects),而是必须转换为 SQL 才能在数据库中执行。

    如果您的查询不可翻译成 SQL 或不支持翻译,您将获得运行时异常。在您的特定情况下,您有一个复杂的内存数据结构 - 您的字典 - 不能在 SQL 查询中使用。

    您必须重写查询才能解决问题。我会在您执行查询后使用字典,例如这样:

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

    【讨论】:

    • 谢谢亲爱的@Slauma。我了解 IEnumerable 和 IQueryable 的区别。再次感谢您的帮助。
    猜你喜欢
    • 2010-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-17
    相关资源
    最近更新 更多