【问题标题】:Computed Columns in EF using LINQEF 中使用 LINQ 的计算列
【发布时间】:2013-10-25 22:07:34
【问题描述】:

使用以下代码;

  using (var context = new FINSAT613Entities())
        {
            gridControl1.ForceInitialize();



            DateTime endtime= new DateTime(2013, 03, 29, 15, 49, 54);
            Text = "endtime:"+endtime.ToShortDateString();


            var query =
                from A in context.A
                join B in context.B on A.ID equals B.ID
                join C in context.C on A.ID2 equals C.ID2
                where A.endtime> endtime && A.Chk.StartsWith("320")
                select new
                       {
                         A.ID,B.FOO,C.BAR etc...
                       };


            BindingSource.DataSource = query;
            gridControl1.DataSource = BindingSource;
        }

如何向其中添加计算列?(例如,将 a.bar 与 b.foo 相乘)

尝试使用部分类,但没有运气。

    public partial class A
{
    public decimal Calculated
    {
        get { return 15; }
    }
}

我得到的确切错误是:

{"LINQ to Entities 不支持指定的类型成员 'Computed'。仅支持初始化程序、实体成员和实体导航属性。"}

【问题讨论】:

  • 您的解决方案应该有效,您遇到了什么问题?
  • 更新了我得到的错误...
  • 您是否尝试使用计算列过滤数据?
  • 不,只是做一些测试,它现在只返回 15。

标签: c# linq entity-framework


【解决方案1】:

您可以创建类,其中包含您需要的所有字段:id、foo、bar 等并添加到其中计算字段,然后只需修改您的查询:

var query =
                from A in context.A
                join B in context.B on A.ID equals B.ID
                join C in context.C on A.ID2 equals C.ID2
                where A.endtime> endtime && A.Chk.StartsWith("320")
                select new YourNewClass
                {
                    Foo = A.foo,
                    Bar = B.bar,
                    ... ,
                    Calculated = A.foo * B.bar   
                };

已编辑:如果您有很多字段,可以使用automapper

这是一个例子。比如说,您从数据库中获得了 User 类,并且获得了 UserModel 类,您在其中添加了一个字段 FullName,该字段由字段 Name 和 Surname 组成。因此,您想从对象 User 创建一个对象 UserModel 但不明确复制所有字段。你可以这样做:

class Program
    {
        static void Main(string[] args)
        {
            User u = new User { Name = "My", Surname = "Name" };
            Mapper.CreateMap<User, UserModel>().ForMember(dest => dest.FullName, o => o.MapFrom(src => string.Format("{0} {1}", src.Name, src.Surname)));

            UserModel um = Mapper.Map<User, UserModel>(u);
            Console.WriteLine(um.FullName);
        }
    }

    public class User
    {
        public string Name { get; set; }
        public string Surname { get; set; }
    }

    public class UserModel
    {
        public string Name { get; set; }
        public string Surname { get; set; }
        public string FullName { get; set; }
    }

【讨论】:

【解决方案2】:

你解决了吗?

我自己一直在寻找一种更整洁的方式, 当我想要添加到现有模型中的只是一两条附加信息时,我不喜欢使用 ViewModels。

我倾向于在我的模型中创建一个非映射字段,将我需要的所有信息从 LINQ 获取到一个临时模型中,然后在另一个循环中执行任何所需的重新映射,然后再将其发送回客户端。

例如;

public partial class A
{
[NotMapped]
public decimal Calculated {get;set;}
}

然后在我的 Linq 查询中

var query =
            from A in context.A
            join B in context.B on A.ID equals B.ID
            join C in context.C on A.ID2 equals C.ID2
            where A.endtime> endtime && A.Chk.StartsWith("320")
            select new
                   {
                     A = A,
                     B = B,
                     C = C
                   };
foreach(item i in query)
    {
        A.Calculated = A.Foo * B.Bar;
    }

return query

好吧,这意味着另一个循环,但至少它只是一个 DB 调用。

另一种选择是在 T-SQL 中完成所有操作并直接(或通过存储过程)发出 T-SQL

这个链接解释了如何 - 作为一个额外的好处,这个方法在处理更复杂的查询时要快得多,但对我来说总是感觉有点像 hack。

http://weblogs.asp.net/scottgu/archive/2007/08/16/linq-to-sql-part-6-retrieving-data-using-stored-procedures.aspx

【讨论】:

    【解决方案3】:

    我首先将我的数据放入一个列表中来实现这一点。这可能很糟糕(尤其是当您有大量结果时),但它确实有效且易于理解。

    整个列表都有一个循环。我不确定其他解决方案是否需要这样做,但我目前也很难理解它们,所以我需要一些适合我正在尝试做的事情的东西,即填充 DropDownList。

    我真的不认为这个解决方案是理想的:

    假设我有一个实体YourEntities 和一个表Registration

    using (var context = new YourEntities()) 
    {
        var query = from x in context.Registrations
                    select x; //Just an example, selecting everything.
        List<Registration> MyList = query.ToList();
        foreach (Registration reg in MyList) //Can also be "var reg in MyList"
        {
            MyDropDownList.Items.Add(new ListItem(reg.LastName + ", " + reg.FirstName, reg.ID));
            //Or do whatever you want to each List Item
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-12-23
      • 1970-01-01
      • 2013-03-13
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多