我有一个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
和Supplier
的组织子类,因为在我的域的其他部分使用Organisations
时,这将使事情变得更容易(仅限{{1}这是一个Organisation
可以与采购订单相关联。)
我创建了两个派生自Supplier
类的类。
Organisation
接下来,我想告诉Entity Framework如何将这些类映射到表中。所有信息都将存储在一个名为“组织”的表中,因此我尝试使用TPH(每个层次的表)映射。
以下是我希望我的映射工作的方式:
public class Supplier : Organisation
{
}
public class Customer : Organisation
{
}
,我希望Entity Framework返回所有组织,而不管Organisations
和IsCustomer
属性中的值。IsSupplier
,我希望实体框架返回Suppliers
所有组织。IsSupplier = true
,我希望实体框架返回Customers
所有组织。组织同时兼顾客户和供应商是有效的,因此我希望某些组织可以包含在IsCustomer = true
和Customer
个查询中。
这是我定义的配置类:
Supplier
这会导致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);
});
}
}
被抛出,并显示以下消息:
错误3032:从第59行开始映射片段的问题:条件 会员'Organisation.IsSupplier'的条件不是 'IsNull = False'被映射。要么删除条件 Organisation.IsSupplier或将其从映射中删除。
我不确定如何修复此错误,或者即使我想要做的事情是可能的,因为我看到的所有示例都有一个鉴别器列。我不确定我是否能够通过一个鉴别器实现我想要的结果,因为我需要区分同时是客户和供应商的组织。
更新
经过一些研究后,似乎错误是由于我在DataException
课程中定义了IsSupplier
和IsCustomer
属性。如果我删除这些属性,那么我的数据库正确构建并且我的映射有效(实体框架在我的表中创建单独的鉴别符)。
我已经使用3个单独的查询进行了测试(1个用于选择Organisation
,1个用于选择Organisations
,1个用于选择Customers
),这似乎可以让我得到正确的结果我的解决方案占了90%左右。
我现在遇到的问题是我需要一种从数据库中选择Suppliers
的方法,并且还设置为供应商(因为我没有要设置的属性)。
答案 0 :(得分: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);
});
你当然应该定义一个enum来替换int。
击>
你已经知道了,但是
组织既是客户又是供应商,这是有效的 ....
因为我需要区分既是客户又是供应商的组织。
这完全违背了基本的OOP原则。实例不能是2种派生类型,在C#中不支持。
如果你想实现这个,你需要一个完全不同的设计。
我需要一种方法从数据库中选择一个客户,并且还设置为客户(因为我没有要设置的属性)。
您可以使用OfType<>
方法选择客户或供应商:
IEnumerable<Customer> allCustomers = myContext.Organisations.OfType<Customer>();
您只需将客户添加到公共实体集:
var c = new Customer(....);
myContext.Organisations.Add(c);
通常,您不在查询中使用Discriminator属性。