4

SO (子エンティティのプロパティから基本エンティティをフィルター処理) に関する最初の質問から 1 年以上が経過した後、同様の問題が発生しました。

抽象基本型があります

public abstract class Base{
}

この基本タイプから継承するいくつかの子エンティティがあります

public class Child1 : Base{
    public virtual NavigationProperty NavigationProperty {get; set; }
    public int NavigationPropertyId {get; set}
}

public class Child2 : Base{
    public virtual NavigationProperty NavigationProperty {get; set; }
}

子エンティティにはすべて、NavigationProperty プロパティがあります。そして、NavigationProperty クラスは次のようになります

 public class NavigationProperty{
    public virtual ICollection<Child1> Child1s {get; set;}
    public virtual Child2 Child2s {get; set;}
 }

Child2 と NavigationProperty の間には 1 対 1 のマッピングがあります。Child1 と NavigationProperty の間の一対多の関係。これらのマッピングを機能させるために、TPT を使用しています。私の最初の質問は、移動できますか

  public NavigationProperty NavigationProperty {get; set; }

ベースクラスに?

私はこれを一日中試していますが、成功しませんでした。それが不可能な場合は、少なくとも基本型から NavigationProperty にアクセスできます。すべての子がこのプロパティを持った後、次のようなことを試しました

 public abstract class Base{
      public abstract NavigationProperty NavigationProperty {get; set; }
 }
 ....
 public abstract class Child2{
      public override NavigationProperty NavigationProperty {get; set; }
 }

しかし、エンティティ フレームワークでは次のエラーが発生します。

 Sequence contains more than one matching element 

次のようなものを使用できます

   public abstract class Base{
      public abstract NavigationProperty GetNavigationProperty();
   }

  public abstract class Child2{
      public override NavigationProperty NavigationProperty {get; set; }
      public override NavigationProperty GetNavigationProperty(){
           return NavigationProperty;
      }
 }

しかし、私はこれらの余分なメソッドを導入したくありません。これをよりエレガントに達成する方法はありますか?

編集:

私はすでに[NotMapped]属性を入れてみたことを忘れていました。EF[NotMapped]属性も継承されていると思うので、子プロパティもマップされていません。

Linq-to-Entites が機能するとは思わない。ナビゲーション プロパティを使用してベース エンティティをクエリできるようにしたくありません。GetNavigationProperty および SetNavigationProperty メソッドを削除したいだけです。したがって、基本クラスから NavigationProperty にアクセスしようとすると、メモリにロードする必要があります。それだけです。しかし、1週間の努力の後、私はそれが可能だとは思わない.

4

3 に答える 3

1

移動できますか

public NavigationProperty NavigationProperty {get; set; }

ベースクラスに?

いいえ、エンティティの逆プロパティはではなくとNavigationPropertyを参照するためです。ナビゲーション プロパティは常に宣言された型のプロパティである必要があり、継承チェーン内の基本型に移動することはできません。Child1Child2Base

2 番目の問題については、抽象的なナビゲーション プロパティをマッピングから除外することを試みることができます。

public abstract class Base {
    [NotMapped]
    public abstract NavigationProperty NavigationProperty {get; set; }
}

(またはmodelBuilder.Entity<Base>().Ignore(b => b.NavigationProperty);Fluent API を使用)。

ただしBase.NavigationProperty、LINQ-to-Entities ではマップされていないプロパティを使用できないため、クエリで使用することはできません。

于 2013-03-04T19:05:55.803 に答える
1

EDIT x1プロパティ名のリテラル文字列を避けるためにコードを更新しました

少しの反省が仕事をしているようです。クラスのセットアップ;

public class NavigationProperty
{
    public NavigationProperty(string name)
    {
        Name = name;
    }

    public string Name { get; set; }
}

public abstract class Base
{
    public NavigationProperty NavigationProperty
    {
        get
        {
            string propertyName = MethodBase.GetCurrentMethod().Name.Replace("get_", string.Empty);
            PropertyInfo property = this.GetType().GetProperty(propertyName);
            if (property != null)
            {
                nav = (NavigationProperty)property.GetValue(this, new object[] { });
            }

            return nav;
        }
        set
        {
            string propertyName = MethodBase.GetCurrentMethod().Name.Replace("set_", string.Empty);
            PropertyInfo property = this.GetType().GetProperty(propertyName);
            if (property != null)
            {
                property.SetValue(this, value, new object[] { });
            }
        }
    }
}

public class Child1 : Base {
    public NavigationProperty NavigationProperty { get; set; }
    public int NavigationPropertyId { get; set; }
}

public class Child2 : Base{
    public NavigationProperty NavigationProperty { get; set; }
}

そしてあなたのコードで;

Child1 c1 = new Child1() { NavigationProperty = new NavigationProperty("child1Value") };
Child2 c2 = new Child2() { NavigationProperty = new NavigationProperty("child2Value") };
Base somebase = c1;
NavigationProperty childNav = somebase.NavigationProperty;
// childNav.Name now contains "child1Value"

これはあなたの要件を満たしていますか?メソッドを使用するよりも少し面倒ですabstractが、少なくともすべての子クラスをリファクタリングする必要がないことを意味します

于 2013-03-07T17:52:35.680 に答える
1

シナリオの Entity Framework でサポートを見つけることができない場合は、これを試すことができます。

public interface IHasNavigationProperty {
    NavigationProperty NavigationProperty { get; }
}

public class Child1 : Base, IHasNavigationProperty {
    public NavigationProperty NavigationProperty { get; set; }
}

public class Base {
    public void AMethodThatDoesStuff() {
        if (this is IHasNavigationProperty) {
            var navigationProperty = ((IHasNavigationProperty)this).NavigationProperty;

            /* do stuff with NavigationProperty */
        }
    }
}
于 2013-03-08T01:46:29.050 に答える