0

私は、サプライヤー顧客、またはその両方Organisationになることができるビジネスを表すエンティティを持っています。

エンティティは次のようになります。

public abstract class Organisation
{
    public Organisation()
    {
        IsCustomer = false;
        IsSupplier = false;
    }

    public int Id { get; set; }
    public string Name { get; set; }

    public bool IsSupplier { get; set; }
    public bool IsCustomer { get; set; }
}

Customer私はand と呼ばれる組織のサブクラスを作成しました。これにより、ドメインの他の部分でSupplier作業する際に作業が容易になります (例:であるのみが注文書に関連付けられます)。OrganisationsOrganisationSupplier

クラスから派生する 2 つのクラスを作成しましたOrganisation

public class Supplier : Organisation
{
}

public class Customer : Organisation
{
}

次に、これらのクラスをテーブルにマップする方法を Entity Framework に伝えたいと思います。すべての情報は「組織」と呼ばれる単一のテーブルに保存されるため、TPH (階層ごとのテーブル) マッピングを使用しようとしています。

マッピングを機能させる方法は次のとおりです。

  • を照会する場合、およびプロパティOrganisationsの値に関係なく、Entity Framework がすべての組織を返すようにします。IsCustomerIsSupplier
  • をクエリSuppliersした場合、Entity Framework が を含むすべての組織を返すようにしIsSupplier = trueます。
  • をクエリCustomersした場合、Entity Framework が を含むすべての組織を返すようにしIsCustomer = trueます。

組織が顧客とサプライヤーの両方になることは有効であるため、一部の組織はクエリCustomerSupplierクエリの両方に含まれると予想されます。

定義した構成クラスは次のとおりです。

class OrganisationConfiguration : EntityTypeConfiguration<Organisation>
{
    internal OrganisationConfiguration()
    {
        ToTable("Organisations");
        HasKey(o => o.Id);

        Map<Customer>(m =>
            {
                m.Requires("IsCustomer").HasValue(true);
            });

        Map<Supplier>(m =>
            {
                m.Requires("IsSupplier").HasValue(true);
            });
    }
}

これによりDataException、次のメッセージがスローされます。

エラー 3032: 行 59 から始まるフラグメントのマッピングの問題: 'IsNull=False' 以外の条件を持つ条件メンバー 'Organisation.IsSupplier' がマップされています。Organization.IsSupplier の条件を削除するか、マッピングから削除してください。

このエラーを修正する方法がわかりません。または、私が見たすべての例には単一の識別子列があるため、やりたいことが可能かどうかさえわかりません。顧客とサプライヤーの両方である組織を区別する必要があるため、単一の識別子で希望する結果を達成できるかどうかはわかりません。

アップデート:

いくつかの調査の後、エラーは、クラスで定義されたIsSupplierおよびIsCustomerプロパティを持っていることが原因のようです。Organisationこれらのプロパティを削除すると、データベースが適切に構築され、マッピングが機能します (Entity Framework はテーブルに個別の識別子を作成します)。

これを 3 つの個別のクエリ (1 to select Organisations、1 to select Customers、1 to select Suppliers) でテストしましたが、正しい結果が得られたようで、ソリューションの約 90% に到達しました。

私が今抱えている問題はCustomer、データベースから を選択する方法が必要であり、サプライヤーとしても設定する方法が必要なことです (設定するプロパティがないため)。

4

1 に答える 1

1

今すぐ試すことはできませんが、識別子列は 1 つしか許可されていないと思います。

public abstract class Organisation
{
    ...
    //public bool IsSupplier { get; set; }
    //public bool IsCustomer { get; set; }
    public int SubType { get; set; }
}

   Map<Customer>(m =>
        {
            m.Requires("SubType").HasValue<int>(1);
        });

   Map<Supplier>(m =>
        {
            m.Requires("SubType").HasValue<int>(2);
        });

もちろん、int を置き換える列挙型を定義する必要があります。


あなたはすでにそれを理解していますが、

組織が顧客とサプライヤーの両方であることは有効です
....
顧客とサプライヤーの両方である組織を区別する必要があるためです。

これは、ここでの基本的な OOP 原則に反するだけです。インスタンスを 2 つの派生型にすることはできません。これは C# ではサポートされていません。

これを実装したい場合は、まったく異なる設計が必要です。


データベースから顧客を選択する方法が必要であり、顧客として設定する方法も必要です(設定するプロパティがないため)。

OfType<>次の方法で、Customer または Supplier を選択できます。

 IEnumerable<Customer> allCustomers = myContext.Organisations.OfType<Customer>();

顧客を共通のエンティティ セットに追加するだけです。

var c = new Customer(....);
myContext.Organisations.Add(c);

通常、クエリでは Discriminator プロパティを使用しません。

于 2013-05-07T12:59:26.927 に答える