简体   繁体   中英

Computed Columns in EF using LINQ

With the following code;

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

How can i add computed columns to it?(multiples a.bar with b.foo for example)

Tried using partial class but no luck with it.

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

The exact error i get is :

{"The specified type member 'Computed' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported."}

You can create class, wich has got all the fields you need: id, foo, bar, etc. and add to it Calculated field, then just modify your query:

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

EDITED: if you have got a lot of fields, you can use automapper

Here is an example. Say, you have got class User from your DB and you have got class UserModel, in which you added a field FullName which constist from fields Name and Surname. So you want to create an object UserModel from object User but not to copy all the fields exclicitly. That's how you can do it:

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

Did you solve this?

I've been looking for a neater way myself, I don't like using ViewModels when all I want to add to an existing model is only one or two pieces of additional info.

What I tend to do is create have a non mapped field in my model, get all the info I need from the LINQ into a temporary model and then perform any required remapping in another loop before I send it back to the client.

So for example;

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

then in my Linq Query

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

OK, it means another loop, but at least it's only one DB call.

Another option would be to do it all in T-SQL and issues the T-SQL directly (or via a stored proc)

this link explains how - as an added bonus this method is much faster with more complex queries, but it always feels like a bit of a hack to me.

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

I accomplished this by putting my data into a List first. This is probably terrible (especially if you have a large amount of results) but it does work and is easy to understand.

There's a loop involved going through the whole list. I'm not sure if other solutions require this but I also am currently having a hard time understanding them, so I need something that works for what I was trying to do, which was to populate a DropDownList.

Again I really don't think this solution is ideal:

Let's say I have an entity YourEntities with a table 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
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM