问题描述
我想在 Sub PP_Test()
Const filename = "C:\Example.pptx"
Dim wbk As Workbook,wsh As Worksheet
Dim pptApp As PowerPoint.Application,pptPres As PowerPoint.Presentation
Set pptApp = new PowerPoint.Application
pptApp.Visible = True
Set pptPres = pptApp.Presentations.Open(filename)
Set wbk = Workbooks("Test.xlsm")
'Loop through the slides and loop through the shapes to find all the Tables. Copy the table,and paste them in Excel
Dim s As PowerPoint.Slide,sh As PowerPoint.Shape
For Each s In pptPres.Slides
For Each sh In s.Shapes
'Create a new sheet in Excel
Set wsh = wbk.Worksheets.Add(After:=wbk.Worksheets(wbk.Worksheets.Count))
' Copy/paste the shape/table
sh.Copy
wsh.Paste
Next sh
Next s
End Sub
自定义类和 List
自定义类之间使用 NxProperty
建立双重关系。
NxLog
在 public class NxLog
{
public string NxLogId { get; set; }
public string NxWorkspaceId { get; set; }
public string NxConversationId { get; set; }
public NxConversation NxConversation { get; set; }
public List<NxOutputText> NxOutputTexts { get; set; }
public List<NxProperty> RequestProperties { get; set; } //1st Relation
public List<NxProperty> ResponseProperties { get; set; } //2nd Relation
}
public class NxProperty
{
public string NxPropertyId { get; set; }
public string NxWorkspaceId { get; set; }
public string NxConversationId { get; set; }
public string NxLogId { get; set; }
public NxLog NxLog { get; set; }
public JToken Value { get; set; }
}
女儿班中,我有:
DbContext
但我得到异常:
class CustomDbContext:DbContext
{
DbSet<NxWorkspace> Workspaces { get; set; }
DbSet<NxConversation> Conversations { get; set; }
DbSet<NxLog> Logs { get; set; }
DbSet<NxOutputText> OutputTexts { get; set; }
DbSet<NxProperty> RequestProperties { get; set; }
DbSet<NxProperty> ResponseProperties { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<NxWorkspace>().HasKey(w => w.NxWorkspaceId);
modelBuilder.Entity<NxConversation>().HasKey(c => new { c.NxWorkspaceId,c.NxConversationId });
modelBuilder.Entity<NxLog>().HasKey(l => new { l.NxWorkspaceId,l.NxConversationId,l.NxLogId });
modelBuilder.Entity<NxOutputText>().HasKey(o => new { o.NxWorkspaceId,o.NxConversationId,o.NxLogId,o.NxOutputTextId });
modelBuilder.Entity<NxProperty>().HasKey(p => new { p.NxWorkspaceId,p.NxConversationId,p.NxLogId,p.NxPropertyId });
modelBuilder.Entity<NxProperty>().Property(l => l.Value)
.HasConversion<string>(
o => JsonConvert.SerializeObject(o),d => JsonConvert.DeserializeObject<JToken>(d)
);
//Other steps
}
}
我需要确保我拥有正确的代码。
我正在尝试
System.InvalidOperationException: Unable to determine the relationship represented by navigation 'NxLog.RequestProperties' of type 'List<NxProperty>'. Either manually configure the relationship,or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.ValidatePropertyMapping(IModel model,IDiagnosticsLogger`1 logger)
at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.Validate(IModel model,IDiagnosticsLogger`1 logger)
at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidator.Validate(IModel model,IDiagnosticsLogger`1 logger)
at Microsoft.EntityFrameworkCore.SqlServer.Internal.SqlServerModelValidator.Validate(IModel model,IDiagnosticsLogger`1 logger)
at Microsoft.EntityFrameworkCore.Metadata.Conventions.ValidatingConvention.ProcessModelFinalized(IModel model)
at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelFinalized(IModel model)
at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelFinalized(IModel model)
at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.FinalizeModel()
at Microsoft.EntityFrameworkCore.ModelBuilder.FinalizeModel()
at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context,IConventionSetBuilder conventionSetBuilder,ModelDependencies modelDependencies)
at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context,ModelDependencies modelDependencies)
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_3(IServiceProvider p)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite,RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite,TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite,RuntimeResolverContext context,ServiceProviderEngineScope serviceProviderEngine,RuntimeResolverLock lockType)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite,RuntimeResolverContext context)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(ServiceCallSite callSite,TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite,TArgument argument)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite,ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType,ServiceProviderEngineScope serviceProviderEngineScope)
at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider,Type serviceType)
at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Infrastructure.IInfrastructure<System.IServiceProvider>.get_Instance()
at Microsoft.EntityFrameworkCore.Infrastructure.Internal.InfrastructureExtensions.GetService[TService](IInfrastructure`1 accessor)
at Microsoft.EntityFrameworkCore.Infrastructure.AccessorExtensions.GetService[TService](IInfrastructure`1 accessor)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(Func`1 factory)
at Microsoft.EntityFrameworkCore.Design.Internal.DbContextOperations.CreateContext(String contextType)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name,String outputDir,String contextType,String namespace)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name,String namespace)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Unable to determine the relationship represented by navigation 'NxLog.RequestProperties' of type 'List<NxProperty>'. Either manually configure the relationship,or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
PM>
但我明白...
modelBuilder.Entity<NxLog>()
.HasMany(l => l.RequestProperties)
.WithOne(p => p.NxLog).HasForeignKey(p => p.NxLogId);
modelBuilder.Entity<NxLog>()
.HasMany(l => l.ResponseProperties)
.WithOne(p => p.NxLog).HasForeignKey(p => p.NxLogId);
我必须如何在 Cannot create a relationship between 'NxLog.ResponseProperties' and 'NxProperty.NxLog'
because a relationship already exists between 'NxLog.RequestProperties' and 'NxProperty.NxLog'.
Navigation properties can only participate in a single relationship.
If you want to override an existing relationship call 'Ignore' on the navigation
'NxProperty.NxLog' first in 'OnModelCreating'.
方法中建立关系?
你能和我分享OnModelCreating(ModelBuilder modelBuilder)
的代码吗?
提前致谢
解决方法
我不得不看 9 次才能理解您的代码。所以首先,在我看来,让同一个类代表多个表是错误的。如果您想一起处理它们,请为两者创建一个基类,然后创建子类。这就是您不能正确映射它们的原因,因为名称不明确。但我是来帮忙的。
- 步骤:重构您的
NxProperty
类。
- 使 NxProperty 成为抽象类。
- 创建一个空类,该类继承自名为
NxRequestProperty
的此类。 - 创建另一个从该类继承的名为
NxResponseProperty
的空类。
示例:
//NgProperty.cs
public abstract class NxProperty
{
public string NxPropertyId { get; set; }
public string NxWorkspaceId { get; set; }
public string NxConversationId { get; set; }
public string NxLogId { get; set; }
public NxLog NxLog { get; set; }
public JToken Value { get; set; }
}
// NxRequestProperty.cs
// using sealed is just my preference so other
// developers know not to inherit from it without
// asking questions,you can exclude it if you wish.
public sealed class NxRequestProperty : NxProperty {
}
// NxResponseProperty.cs
public sealed class NxResponseProperty : NxProperty {
}
- 步骤:重构您的
NxLog
类。使用具体类而不是NxProperty
抽象类。
示例:
// NxLog.cs
public sealed class NxLog
{
public string NxLogId { get; set; }
public string NxWorkspaceId { get; set; }
public string NxConversationId { get; set; }
public NxConversation NxConversation { get; set; }
public List<NxOutputText> NxOutputTexts { get; set; }
public List<NxRequestProperty> RequestProperties { get; set; }
public List<NxResponseProperty> ResponseProperties { get; set; }
}
- 步骤:重构您的
CustomDbContext
。您的NxProperty
类现在是抽象的,您不应该将它用作DbSet
(恕我直言),让我们重构它。
示例:
// CustomDbContext.cs
public sealed class CustomDbContext : DbContext
{
DbSet<NxWorkspace> Workspaces { get; set; }
DbSet<NxConversation> Conversations { get; set; }
DbSet<NxLog> Logs { get; set; }
DbSet<NxOutputText> OutputTexts { get; set; }
// Refactor starts here!
DbSet<NxRequestProperty> RequestProperties { get; set; }
DbSet<NxResponseProperty> ResponseProperties { get; set; }
// Refactor ends here!
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<NxWorkspace>().HasKey(w => w.NxWorkspaceId);
modelBuilder.Entity<NxConversation>().HasKey(c => new { c.NxWorkspaceId,c.NxConversationId });
modelBuilder.Entity<NxLog>().HasKey(l => new { l.NxWorkspaceId,l.NxConversationId,l.NxLogId });
modelBuilder.Entity<NxOutputText>().HasKey(o => new { o.NxWorkspaceId,o.NxConversationId,o.NxLogId,o.NxOutputTextId });
// Refactor starts here!
modelBuilder.Entity<NxRequestProperty>().HasKey(p => new { p.NxWorkspaceId,p.NxConversationId,p.NxLogId,p.NxPropertyId });
modelBuilder.Entity<NxResponseProperty>().HasKey(p => new { p.NxWorkspaceId,p.NxPropertyId });
modelBuilder.Entity<NxRequestProperty>().Property(l => l.Value)
.HasConversion<string>(
o => JsonConvert.SerializeObject(o),d => JsonConvert.DeserializeObject<JToken>(d)
);
modelBuilder.Entity<NxResponseProperty>().Property(l => l.Value)
.HasConversion<string>(
o => JsonConvert.SerializeObject(o),d => JsonConvert.DeserializeObject<JToken>(d)
);
// Refactor ends here!
//Other steps
}
}
- (和最后一步):我不确定 EF Core 现在是否可以映射关系,但我相信始终声明的源代码是更好的源代码,所以这里是如何映射它。由于有复合键,您需要将外键作为所有复合键。
示例:
// CustomDbContext.cs -> inside the OnModelCreating method
modelBuilder.Entity<NxRequestProperty>
.HasOne(p => p.NxLog)
.WithMany(l => l.RequestProperties)
.HasForeignKey(l => new { l.NxWorkspaceId,l.NxLogId });
modelBuilder.Entity<NxResponseProperty>
.HasOne(p => p.NxLog)
.WithMany(l => l.ResponseProperties)
.HasForeignKey(l => new { l.NxWorkspaceId,l.NxLogId });
编辑:
看着我的回答,我意识到将 NxProperty
重构为接口可能更好(并将其称为 INxProperty
)。两者都可以,但我认为界面更适合于此。