简体   繁体   中英

LINQ to Entities - Best way to accomplish this?

OK, I am mostly a LAMP developer so I am new to the entity framework. However, I am familiar with the basics in LINQ and have generated a entity model from my DB. Now here is my requirement:

I have a datagrid on a WinForm that will be refreshed from a data source on a remote server every few seconds as changes to the dataset are made from other sources. Obviously, I'd like to construct a lambda expression to get the right anonymous type to satisfy the columns that needs to be shown in my datagrid. I have done this and here is the result (I'm using a custom datagrid control, btw):

替代文字

And my code thus far:

Models.dataEntities objDB = new Models.dataEntities();

var vans = from v in objDB.vans
           select v;

gcVans.DataSource = vans;

OK, so now I have my basic data set. One problem I had is that the "Status" column will show a calculated string based on several parameters in the data set. I added this to my entities via a partial class. As you can see in the screenshot, this is working correctly:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace WindowsFormsApplication1.Models {

    public partial class van {

        public string van_status {

            get {

                if (this.is_offline == 1) {

                    return "Offline";

                } else if (this.is_prayer_room == 1) {

                    return "In Prayer Room";

                } else {

                    return "TODO: Create statuses";

                }

            }

        }

    }

}

This added property works fine. However, the second I try to project the status in an anonymous type so I can also retrieve the school name, I get an error:

Models.dataEntities objDB = new Models.dataEntities();

var vans = from v in objDB.vans
           select new {

               van_name = v.van_name,
               school_name = v.school.school_name,
               capacity = v.capacity,
               phone = v.phone,
               van_status = v.van_status

           };

gcVans.DataSource = vans;

替代文字

So, I have two questions:

1) If I cannot use computed properties of my partial classes in LINQ projections, how am I supposed to show my computed string in my datagrid?

2) Am I even approaching this correctly? When I resolve #1, how would I refresh this data (ie during a timer fire event)? Would I simply call objDB.refresh() and then tell my datagrid to update from the datasource? Does calling that method actually run the lambda expression above or does it load everything from the DB?

Thanks for any assistance with this. Also, if you have any best practices to share that would be awesome! I hope I explained this as thoroughly as you need to provide assistance.

1) Instead of modifying your EF object with a partial class you could always create your own class that contains your read only property van_status. The code you've got would be nearly identical:

Models.dataEntities objDB = new Models.dataEntities();
gcVans.DataSource = from v in objDB.vans
           select new DisplayVan {
               van_name = v.van_name,
               school_name = v.school.school_name,
               capacity = v.capacity,
               phone = v.phone,
           };

The van_status property, since it's read-only, will not need to be specified in the query.

2) I'm more a web developer than a desktop developer so I'll give you my take on how to refresh the grid (it may not be the preferred methodology for fat clients)...

I'm reluctant to trust .Refresh() methods and hope all works to maximal efficiency and work properly. Instead, encapsulate the code from #1 in a method of your own and invoke it from your timer event firing (or however you choose to implement the periodic refresh).

Another good option would be to create an extension method.

Here is a simple example:

using System;

namespace WindowsFormsApplication1 {
    static class Program {
        [STAThread]
        static void Main() {
            Van van = new Van();
            string status = van.GetStatus();
        }
    }

    public static class VanExtension {
        public static string GetStatus(this Van van) {
            if(van.is_offline == 1) {
                return "Offline";
            }
            else if(van.is_prayer_room == 1) {
                return "In Prayer Room";
            }

            return "TODO:  Create statuses";
        }
    }

    public class Van {
        public int is_offline { get; set; }
        public int is_prayer_room { get; set; }
    }
}
  • Be sure to put this extension class in the same namespace as the entity class.

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