5

そのため、Entity Framework デザイナーを使用して MVVM プロジェクトのモデルとして機能する EDMX を作成するというウサギの穴からはかなり離れています。ICollection<>生成されたコード (たとえば、以下を参照) は、ObservableCollection<>そのコレクションをDataGridビュー内のにバインドするために本当に必要であると確信している問題に遭遇しました。EFコード生成を変更しObservableCollectionsICollections. 成功した人はいますか?

別のオプションとして、選択した Customer オブジェクトを含む VMObservableCollection<Order>に、Customer オブジェクトが選択されたときに作成されるローカルも含まれていると思います.... コンテキストの保存とデータの同期が心配です。

子オブジェクトのコレクションに関連付けられた典型的なコード生成オブジェクト:

    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通常、 your を介して公開されるクラスには、でDbContextあるLocalプロパティがありObservableCollection<T>ます。詳細については、公式ドキュメントを参照してください

于 2013-06-12T20:17:21.560 に答える
4

あなたのdata logicandは、あなたの and とmodelsは別にする必要がviewmodelあります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));
    }
}

3 つの追加の using ステートメントを含める必要がありました。

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

これは、Getter と Setter を実装するために CodeStringGenerator で変更した関数です: (申し訳ありませんが、これをより読みやすくすることはまだできていません)。

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 に答える