我有一个问题,我无法通过谷歌解决或搜索stackoverflow。
我有两个表JournalLines和Accounts,我想在journalline中引用一个帐户(我讨厌经济学),但引用必须是可选的,并且Account shoulnt具有JournalLine的任何导航属性(理想情况下)。
JournalLine:
public class JournalLine : Entity<int>
{
public int? Account_Id { get; set; }
public string Desc { get; set; }
public decimal Credit { get; set; }
public decimal Debit { get; set; }
public virtual Account Account { get; set; }
}
_account:
public class Account : Entity<int>
{
public string Accid { get; set; }
public string Desc { get; set; }
public int VatcodeId { get; set; }
}
各自的映射:
public class JournalLineMap : EntityTypeConfiguration<JournalLine>
{
public JournalLineMap()
{
HasKey(k => new { k.Id, k.Account_Id });
Property(k => k.Id)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
ToTable("attJournalLines");
HasEntitySetName("JournalLines");
HasOptional(jl => jl.Account)
.WithMany()
.HasForeignKey(jl => jl.Account_Id);
}
}
public class AccountMap : EntityTypeConfiguration<Account>
{
public AccountMap()
{
ToTable("attAccounts");
HasEntitySetName("Accounts");
}
}
我得到的错误就像:
在模型生成期间检测到一个或多个验证错误:
tSystem.Data.Entity.Edm.EdmAssociationType ::多重性与关系“JournalLine_Account”中角色“JournalLine_Account_Target”中的参照&gt;约束冲突。 &gt;由于从属角色中的所有属性都不可为空,因此&gt;主要角色的多重性必须为“1”。
这让我感到困惑,我希望有人可以解决这个问题。
感谢您在途中帮助我的答案,我通过删除密钥获得了工作的关系。然后,在为Account
JournalLine
分配重复帐户时,我得到了一个奇怪的行为。事实证明,这不是一种奇怪的行为,因为我使用具有依赖注入的存储库模式。我没想到的是两个存储库中的上下文不一样,所以JournalLinesRepository没有跟踪我从自己的存储库中获取的帐户,因此认为将它作为新实体插入是明智的。这是通过在存储库中注入相同的上下文来解决的,因此项目跟踪按预期工作。再次谢谢你的帮助。
答案 0 :(得分:3)
通过查看您的代码,它“感觉”像HasKey(k => new { k.Id, k.Account_Id });
一样可能导致问题,因为Account_Id
可以为空,而且通常不会被接受为关键字。尝试删除Account_Id的可空标志只是为了看看会发生什么。
编辑:EF中的键
密钥总是需要在其组合中是唯一的(如果您有多个列和密钥)。这是为什么你不能允许关键参数的空值的基本规则。
当您将其指定为外键时,您已经为Account_Id添加了一个键,那么为什么还要将它作为主键呢?特别是因为你允许它为空?
答案 1 :(得分:3)
Ohlin's Answer正确识别问题 - 您不能拥有可为空列的复合主键。这引发了一些关于你想要建模的问题。
除主键外,您的模型似乎也能正常工作。事实上,我认为删除HasKey(k => new { k.Id, k.Account_Id });
会使事情奏效。如果您这样做,则每个JournalLine
都会拥有自己的唯一ID,并且可选地与Account
相关。
这将产生如下数据:
| AccountId | Desc |
| 123456789 | Some Account |
| JournalId | AccountId | Description | Credit | Debit |
| 1 | null | Some Tx | 100.00 | 0.0 |
| 2 | 123456789 | Another Tx | 0.0 | 50.0 |
| 3 | 123456789 | MoreTx | 10.00 | 0.0 |
另一方面,如果您在AccountId
密钥中使用JournalLine
的原因是暗示每个帐户实际上都有自己的日记帐(这听起来对我的帐户类很熟悉),那么建模需要一些调整 - 或者您可能需要一个特殊的“未分类”帐户专门处理未应用于特定帐户的交易。