5

因此,我在使用实体框架设计器制作一个用作 MVVM 项目中模型的 EDMX 的兔子洞里还差得很远。我刚刚遇到一个问题,我很确定ICollection<>生成的代码(例如见下文)确实需要将ObservableCollection<>集合绑定到 aDataGrid才能成功。我认为我对修改 EF 代码生成以使ObservableCollections而不是ICollections. 有人试过成功吗?

我想另一种选择是让包含所选客户对象的虚拟机还包含一个在选择客户对象ObservableCollection<Order>时创建的本地...我只是担心上下文保存和保持数据同步。

与子对象集合关联的典型代码生成对象:

    public partial class Customer
{
    public Customer()
    {
        this.Orders = new HashSet<Order>();
    }

    public int Id { get; set; }
    public System.DateTime Date { get; set; }

    public virtual ICollection<Order> Orders { get; set; }
}
4

4 回答 4

8

这就是我所做的,并且首先使用 EF 数据库对我有用。

这就是您需要生成的内容:

public partial class Parent
{
    public Parent()
    {
        this.Children= new ObservableCollection<Child>();
    }

这样默认的构造函数将被替换。而且 ObservableCollection 是 ICollection,所以你不需要改变任何其他东西。

要在每次更新数据库模型时显示此内容,您必须使用以下部分更改 .tt 文件:

public string UsingDirectives(bool inHeader, bool includeCollections = true)
{
    return inHeader == string.IsNullOrEmpty(_code.VsNamespaceSuggestion())
        ? string.Format(
            CultureInfo.InvariantCulture,
            "{0}using System;{1}" +
            "{2}",
            inHeader ? Environment.NewLine : "",
            includeCollections ? (Environment.NewLine + "using System.Collections.ObjectModel;" 
                + Environment.NewLine + "using System.Collections.Generic;") : "",
            inHeader ? "" : Environment.NewLine)
        : "";
}

和这个:

    foreach (var navigationProperty in collectionNavigationProperties)
    {

    this.<#=code.Escape(navigationProperty)#> = new ObservableCollection<<#=typeMapper.GetTypeName(navigationProperty.ToEndMember.GetEntityType())#>>();
    }
于 2014-03-15T10:05:06.197 回答
4

DbSet通常通过您公开的类DbContext具有一个Local属性,即ObservableCollection<T>. 更多信息见官方文档

于 2013-06-12T20:17:21.560 回答
4

你的data logicandmodels应该与你的viewmodeland分开models。因此,我认为更好的选择是您在创建ObservableCollection. 保存时,您始终可以同步到上下文(我忘记了要同步的确切语法)。

于 2013-06-12T19:00:40.230 回答
3

是的,我已经这样做了,它成功地适用于我的业务应用程序。我将 Model.tt 文件修改为具有 virtualObservableCollection<T>而不是ICollection<T>并将其替换HashSet<T>为相同的。

我还INotifyPropertyChanged通过以下实现在实体上实现:

public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
    var handler = PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

我需要包含三个额外的 using 语句:

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Collections.ObjectModel;

这是我在 CodeStringGenerator 中更改以实现我的 getter 和 setter 的函数:(对不起,我还没有来使这个更具可读性)

public string Property(EdmProperty edmProperty)
{
    var fourSpaces = "    ";
    return string.Format(
        CultureInfo.InvariantCulture,
        "{0} {1} _{2};{3}{4}{0} {1} {2}{3}{4}{{{3}{4}{4}{5}get {{ return _{2}; }} {3}{4}{4}{6}set{3}{4}{4}{{{3}{4}{4}{4}if (value == _{2}) return;{3}{4}{4}{4}_{2} = value;{3}{4}{4}{4}NotifyPropertyChanged();{3}{4}{4}}}{3}{4}}}{3}",
        Accessibility.ForProperty(edmProperty),
        _typeMapper.GetTypeName(edmProperty.TypeUsage),
        _code.Escape(edmProperty),
        Environment.NewLine,
        fourSpaces,
        _code.SpaceAfter(Accessibility.ForGetter(edmProperty)),
        _code.SpaceAfter(Accessibility.ForSetter(edmProperty)));
}

这是一个完整生成的实体文件示例供参考:

namespace Eagl.Eagle.Data
{
    using System;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;

    public partial class Game : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public Game()
        {
            this.Playtests = new ObservableCollection<Playtest>();
        }

        public int _Id;
        public int Id
        {
            get { return _Id; } 
            set
            {
                if (value == _Id) return;
                _Id = value;
                NotifyPropertyChanged();
            }
        }

        public string _Name;
        public string Name
        {
            get { return _Name; } 
            set
            {
                if (value == _Name) return;
                _Name = value;
                NotifyPropertyChanged();
            }
        }


        public virtual ObservableCollection<Playtest> Playtests { get; set; }
    }
}
于 2013-08-19T00:40:42.960 回答