你如何让EntityFramework 6.1支持过滤和双向绑定,如adapter.Fill(table)呢?

时间:2014-10-06 18:05:52

标签: c# repository-pattern entity-framework-6

我试图让EntityFramework 6.1.1返回一个ObserveableCollection或一个IEnumerable,它支持WinForm中的过滤,排序和绑定(双向)。只要它是Bindable并且支持过滤和排序,我完全不关心实体的格式是什么。我想adapter.Fill(table)是如何工作的,但只是将EntityFramwork作为主干。 如果尝试返回_context.Orders.Local.ToBindingList(); 但是关联的OrderDetails实体不可排序,也不能过滤它们。 如果我将Where表达式附加到Orders它将它转换为IEnumerable并且我无法过滤它们,也不能立即编辑它们。 在这种情况下,通用存储库模式会有帮助吗?如果是这样,请您回复代码示例吗?

这是我的简化订单类:

    public class Orders
    {
        public Orders()
        {
            Details = new HashSet<OrderDetails>();
        }

        [Key]
        public int OrderId {get; set}
        public int CustomerId {get; set;}
        public decimal OrderTotal { get; set;}
        public DateTime OrderDate {get; set;}

        public virtual ICollection<OrderDetails> Details {get; set;}
        public virtual Customer Customer {get; set;}
    }

我有一个ClassLibrary,我尝试过以下三种方法。如果实体尚未加载,则InitDatabase()方法加载实体。

方法#1:

    public static ObservableCollection<ZSA_TransactionDetail> GetAllDetailsAsObservableCollection()
    {
        InitDatabase();
        return NContext.ZSA_TransactionDetail.Local;
    }

方法#2:

    public static ICollection<ZSA_TransactionDetail> GetAllDetailsAsICollection(int orderNumber = 1022)
    {
        InitDatabase();
        ICollection<ZSA_TransactionDetail> iCollection = null;

        ObservableCollection<ZSA_TransactionHeader> headers = NContext.ZSA_TransactionHeader.Local;
        ZSA_TransactionHeader myHeader = headers.FirstOrDefault(i => i.intTransactionNumber == orderNumber);
        if (myHeader != null)
        {
            iCollection = myHeader.ZSA_TransactionDetail;
        }

        if (iCollection != null)
            Debug.WriteLine("iCollection Record Count was: " + iCollection.Count);
        else
            Debug.WriteLine("iCollection was null");

        return iCollection;
    }

方法#3:

    public static BindingList<ZSA_TransactionDetail> GetAllDetailsAsBindingList(int orderNumber = -1)
    {
        InitDatabase();
        if (orderNumber != -1 && IsValidTransaction(orderNumber))
        {
            BindingList<ZSA_TransactionDetail> details = NContext.ZSA_TransactionDetail.Local.ToBindingList();
            var myDetails =
                details.Where(i => i.intTransactionNumber == orderNumber) as BindingList<ZSA_TransactionDetail>;
            if (myDetails != null)
            {
                Debug.WriteLine("Number of details: " + myDetails.Count);
                return myDetails;
            }
            throw new Exception("Did not find any details");
        }
        Debug.WriteLine("Not a valid Transaction Number");
        return NContext.ZSA_TransactionDetail.Local.ToBindingList();
    }

调用方法#2时,我的Form_Load事件如下所示:

    private void FormPick_Load(object sender, EventArgs e)
    {
        ICollection<ZSA_TransactionDetail> data = Library.GetAllDetailsAsICollection(_transactionNumber);

        PickingBindingSource.RaiseListChangedEvents = true;

        PickingBindingSource.DataSource = data;

        Debug.WriteLine("Supports Filter: " + PickingBindingSource.SupportsFiltering);

        PickingGridView.DataSource = PickingBindingSource;

        ApplyFilter();
    }

所有三种方法都报告支持伪造。

1 个答案:

答案 0 :(得分:1)

编辑:更好地解释
上下文集中的本地属性是一个可观察的集合。

  

在这种情况下,通用存储库模式会有所帮助吗?

是的,在这种情况下,这是一种常见的模式 所以使用通用的Repository<T>模式 使用如下方法:

 public ObservableCollection<TPoco> Local {
        get { return Context.Set<TPoco>().Local; }
    }

这使您可以访问相关POCO的上下文加载对象。

使用常规方法在访问Local对象之前填充。

同时查看Context.Configuration.AutoDetectChangesEnabled = <bool>;

尝试加载一些对象的简单测试用例。 然后通过本地属性访问对象,进行简单的更改或2 和SaveChanges()

然后尝试收集绑定。