通过Linq到实体设置扩展属性

时间:2011-01-24 19:21:54

标签: c# entity-framework partial-classes

我想检索数据,并设置在飞行中添加到entityobject(通过部分类)的属性。

我该怎么做?

这是我的疑问:

var ret = (from item in contex.Items
               select new Itemm
               {   
                  Title = item.Title,
                  Count = 1 // more complex: Count =item.refToAnotherEntity.Count()                                          
               });

public partial class Itemm 
{
     public int Count { get; set; }
}

我得到的错误是:无法在LINQ to Entities查询中构造实体或复杂类型

4 个答案:

答案 0 :(得分:0)

问题是Linq to Entities正在尝试将整个表达式转换为SQL。你的“新”声明并不完全可能。

尝试以下方法:

var ret = (from item in contex.Items
           select new Itemm
           ).ToList();
ret = (from item in ret
       select new Itemm
           {   
              Title = item.Title,
              Count = 1                                           
           }).ToList();

在尝试重新构造结果之前,基本上你确保从SQL服务器返回结果(ToList()执行此操作)。它不漂亮,你可以清理一下,但上面的代码应该可以工作。

答案 1 :(得分:0)

您的查询不会转换为正确的SQL,因为linq不知道如何处理您的额外属性。

有一些方法可以初始化自定义属性。

您可以创建

部分无效OnCreated()    {}

在这里编写自定义初始化,如果你 想要在从数据库加载后加载然后就可以了 覆盖

protected override void OnLoaded(bool initial)    {        base.OnLoaded(初始);    }

答案 2 :(得分:0)

我正在努力达到你想要的结果。 到目前为止,我最好的解决方案是为我的实体创建一个Wrapper,它具有Count属性来设置分部类的额外属性。 以你的情况为例,这就像是:

public class ItemWithCount
{
   public Item Item { get; set; }
   public int Count
   {
        get { return Item.Count; }
        set { Item.Count = value; }
   }
}

然后你可以这样查询:

var ret = (from item in contex.Items
           select new ItemWithCount
           {   
              Item = item,
              Count = item.refToAnotherEntity.Count()                                          
           }).AsEnumerable().Select(x => x.Item);

您可以选择具有相同2个属性的匿名类型,而不是创建包装器,但这意味着在查询之后您必须遍历结果并设置每个实体的属性Count的值。像这样:

var ret = (from item in contex.Items
           select new
           {   
              Item = item,
              Count = item.refToAnotherEntity.Count()                                          
           });
Parallel.ForEach(ret, x => x.Item.Count = x.Count);
var results = ret.Select(x => x.Item);

我喜欢第一个选项,但是我想要一个解决方案,而不必创建一个新类...任何想法?

答案 3 :(得分:-1)

如果您愿意将处理转移到客户端(即从IQueryable<T>移至IEnumerable<T>),那么您可以执行以下操作:

var query = (from item in context.Items
    select new Item {                     
        Title = item.Title
    });

var ret = query.AsEnumerable().Select(i => {
    // Set the count.
    i.Count = 1;

    // Return the item.
    return i;
});

关键是下降到IEnumerable<T>,此时,LINQ提供程序变为LINQ to Objects,它不会给你这个问题。