gpt4 book ai didi

c# - EF 代码优先 : Defining foreign keys

转载 作者:太空宇宙 更新时间:2023-11-03 11:25:10 25 4
gpt4 key购买 nike

我看过其他一些答案和很多文章,但这个简单的部分仍然让我望而却步。我首先使用 EF 代码 4.1,但如果它更容易,我很乐意迁移到更新的版本。我有一个像这样的主要事实表:

namespace Spend.Models
{
public class ExpenseItem
{
[Key]
public String UniqueID_ERLineID { get; set; }
public String ERNum { get; set; }
public String ItemNum { get; set; }
public String Parent_Expense_Item { get; set; }
public String Card_Number { get; set; }
...

还有几个表卡在与 ExpenseItems 有多对一关系的表上:

public class ExpenseItemAccounting
{
[Key]
public String UniqueID_Accounting { get; set; }
public String ERLineID { get; set; }
public String ERNum { get; set; }
public String ItemNum { get; set; }

正如我们所见,第二个表中的 ERLineID 连接到第一个表中的 UniqueID_ErLineID,因此我通常依赖的“约定”不起作用。所以我需要使用虚拟 ICollection - 但我希望它将这些字段指定为链接。感谢任何有关如何执行此操作的帮助。

附言。我目前无法重命名数据库字段。

@卢克:

我应用了您提到的更改,它们很有意义。但是我收到以下错误:

System.Data.Entity.ModelConfiguration.ModelValidationException occurred
Message=One or more validation errors were detected during model generation:

System.Data.Edm.EdmAssociationType: : Multiplicity conflicts with the referential constraint in Role 'ExpenseItemAccounting_ExpenseItem_Target' in relationship 'ExpenseItemAccounting_ExpenseItem'. Because all of the properties in the Dependent Role are non-nullable, multiplicity of the Principal Role must be '1'.
System.Data.Edm.EdmAssociationEnd: : Multiplicity is not valid in Role 'ExpenseItemAccounting_ExpenseItem_Source' in relationship 'ExpenseItemAccounting_ExpenseItem'. Because the Dependent Role refers to the key properties, the upper bound of the multiplicity of the Dependent Role must be �1�.

Source=EntityFramework
StackTrace:
at System.Data.Entity.ModelConfiguration.Edm.EdmModelExtensions.ValidateAndSerializeCsdl(EdmModel model, XmlWriter writer)
at System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo)
at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)
at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input)
at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
at System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)
at System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()
at System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()
at System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider()
at System.Linq.Queryable.SelectMany[TSource,TCollection,TResult](IQueryable`1 source, Expression`1 collectionSelector, Expression`1 resultSelector)
at EmailClient.Prog.getData() in C:\MF\Dropbox\Dev_LN_Projects\04_QA\EmailClient\EmailClient\Prog.cs:line 172
InnerException:

这是在我尝试以下 linq 查询时出现的:

        var geee = (from e in db.ExpenseItems
from f in db.ExpenseItemFbtItems
where
e.Item_Transaction_Date.Value.Year == 2011 &&
e.Item_Transaction_Date.Value.Month == 8
select new { A = e.UniqueID_ERLineID, B = f.ERLineID.First() });

我实际上希望能够说出 e.ExpenseItemAccounting.ItemNum 或类似的东西 - 我是否需要在 ExpenseItem 定义中添加一些东西才能实现这一点?

我的模型设置如下。 base.OnModelCreating 是通过 intellisense 出现的,我已经尝试过使用/不使用它以获得相同的结果:

public class SpendDB : DbContext
{
public DbSet<ExpenseAttachment> ExpenseAttachments {get; set; }
public DbSet<ExpenseComment> ExpenseComments {get; set; }
public DbSet<ExpenseItemAccounting> ExpenseAccountings {get; set; }
public DbSet<ExpenseItemFbtItem> ExpenseItemFbtItems {get; set; }
public DbSet<ExpenseItem> ExpenseItems {get; set; }
public DbSet<ExpenseItemViolation> ExpenseItemViolations {get; set; }

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<ExpenseItemAccounting>().HasOptional(e => e.ExpenseItem).WithMany().HasForeignKey(e => e.UniqueID_Accounting);
}
}

也许我需要将虚拟 ICollection 放入 ExpenseItem 定义中?或者它可能是另一种方式 - 说 modelBuilder.Entity 有可选的 ExpenseItemAccounting?这对我来说听起来更直观,但我(显然)不是很擅长这个,所以对它持保留态度!

再次感谢

最佳答案

这样做:

public class ExpenseItemAccounting
{
[Key]
public String UniqueID_Accounting { get; set; }
public ExpenseItem ExpenseItem{get;set;}
public String ERLineID { get; set; }
public String ERNum { get; set; }
public String ItemNum { get; set; }
}

然后在你的模型构建器中使用

modelBuilder.Entity<ExpenseItemAccounting>()
.HasOptional(e => e.ExpenseItem).WithMany()
.HasForeignKey(e => e.UniqueID_Accounting );

编辑:

要将导航属性配置为在另一端有一个集合,您可以像这样简单地添加它

public class ExpenseItem
{
[Key]
public String UniqueID_ERLineID { get; set; }
public String ERNum { get; set; }
public String ItemNum { get; set; }
public String Parent_Expense_Item { get; set; }
public String Card_Number { get; set; }
public ICollection<ExpenseItemAccounting> ExpenseItemAccountings{ get; set; }
}

然后通过如下修改模型构建器配置来连接它:

 modelBuilder.Entity<ExpenseItemAccounting>()
.HasOptional(e => e.ExpenseItem).WithMany(e=> e.ExpenseItems)
.HasForeignKey(e => e.UniqueID_Accounting );

这会将它连接起来,以便 ExpenseItem 将具有所有子 ExpensItemAccounting 的列表,如果这样更有意义,您还可以添加它的单一版本,例如:

 public class ExpenseItem
{
[Key]
public String UniqueID_ERLineID { get; set; }
public String ERNum { get; set; }
public String ItemNum { get; set; }
public String Card_Number { get; set; }
public ExpenseItemAccounting Parent_Expense_Item { get; set; }
}

并使用模型构建器进行配置:

modelBuilder.Entity<ExpenseItemAccounting>()
.HasOptional(e => e.ExpenseItem)
.WithOptionalDependent(e=>e.Parent_Expense_Item);

我想如果您还想连接 FK 引用(不仅仅是导航属性),您需要在单独的语句中执行此操作,但这有点麻烦。

查看有关导航属性的 MSDN 页面以及如何使用 modelBuilder,因为它有很多很好的高级示例。

http://msdn.microsoft.com/en-us/library/hh295843(v=vs.103).aspx

关于c# - EF 代码优先 : Defining foreign keys,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9612611/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com