我正在尝试对 Advertisement
进行更新插入包含 List<AdImage>
的对象. Advertisement
包含对应于 User
的外键. user
可以有零个或多个 Advertisements
, 和一个 Advertisement
有一个或多个 AdImages
.
更新插入失败并显示以下内容:
An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.
内部异常在哪里:
Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values.
advertisement
非常简单地实例化为:
var ad = new Advertisement
{
AdImages = new List<AdImage>
{
new AdImage {Image = model.Image}
},
Message = model.Message,
Title = model.Title,
User = user,
};
_aAdAppService.UpsertAdvertisement(ad);
有问题的实体定义为:
public class User : AbpUser<Tenant, User>
{ // AbpUser is a 3rd party class which defines Id as a primary key
public string AccessToken { get; set; }
public long UserId { get; set; }
public virtual List<Advertisement> Advertisements { get; set; }
}
public class Advertisement : Entity
{
[Key]
public long Id { get; set; }
public string Title { get; set; }
public string Message { get; set; }
public List<AdImage> AdImages { get; set; }
public virtual User User { get; set; }
}
public class AdImage : Entity
{
[Key]
public int Id { get; set; }
public string Image { get; set; }
public virtual Advertisement Advertisement { get; set; }
}
关系是这样定义的:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasMany(u => u.Advertisements)
.WithRequired(x => x.User);
modelBuilder.Entity<Advertisement>()
.HasMany(a => a.AdImages)
.WithRequired(x => x.Advertisement);
modelBuilder.Entity<AdImage>()
.HasRequired(x => x.Advertisement);
base.OnModelCreating(modelBuilder);
}
错误信息是什么意思?我看不出我的关系是如何被错误定义的。我该如何解决这个问题?
最佳答案
这只是一条评论,但我不能在评论中写...
第一次看到异常
Unable to determine a valid ordering for dependent operations. Dependencies may exist due to foreign key constraints, model requirements, or store-generated values.
所以我尝试复制它。
这是我实现错过的类(class)和上下文的方式
public class Entity
{}
public class Tenant
{}
public class AbpUser<T1, T2>
{}
public Context(DbConnection connection)
: base(connection, false)
{
}
public DbSet<Advertisement> Advertisements { get; set; }
public DbSet<User> Users { get; set; }
public DbSet<AdImage> AdImages { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>()
.HasMany(u => u.Advertisements)
.WithRequired(x => x.User);
modelBuilder.Entity<Advertisement>()
.HasMany(a => a.AdImages)
.WithRequired(x => x.Advertisement);
modelBuilder.Entity<AdImage>()
.HasRequired(x => x.Advertisement);
base.OnModelCreating(modelBuilder);
}
这是EF在自动迁移时生成的DDL语句
ExecuteNonQuery==========
CREATE TABLE [AdImages] (
[Id] int not null identity(1,1)
, [Image] text null
, [Advertisement_Id] int not null
);
ALTER TABLE [AdImages] ADD CONSTRAINT [PK_AdImages_87d4bad2] PRIMARY KEY ([Id])
ExecuteNonQuery==========
CREATE TABLE [Advertisements] (
[Id] int not null identity(1,1)
, [Title] text null
, [Message] text null
, [User_UserId] int not null
);
ALTER TABLE [Advertisements] ADD CONSTRAINT [PK_Advertisements_5d578c9a] PRIMARY KEY ([Id])
ExecuteNonQuery==========
CREATE TABLE [Users] (
[UserId] int not null identity(1,1)
, [AccessToken] text null
);
ALTER TABLE [Users] ADD CONSTRAINT [PK_Users_5d578c9a] PRIMARY KEY ([UserId])
ExecuteNonQuery==========
CREATE INDEX [IX_Advertisement_Id] ON [AdImages] ([Advertisement_Id])
ExecuteNonQuery==========
CREATE INDEX [IX_User_UserId] ON [Advertisements] ([User_UserId])
ExecuteNonQuery==========
ALTER TABLE [AdImages] ADD CONSTRAINT [FK_AdImages_Advertisements_Advertisement_Id] FOREIGN KEY ([Advertisement_Id]) REFERENCES [Advertisements] ([Id])
ExecuteNonQuery==========
ALTER TABLE [Advertisements] ADD CONSTRAINT [FK_Advertisements_Users_User_UserId] FOREIGN KEY ([User_UserId]) REFERENCES [Users] ([UserId])
所以,其实一切都如我们所料。
这里是我试过的测试
public static void Run(DbConnection connection)
{
var ad = new Advertisement
{
AdImages = new List<AdImage>
{
new AdImage {Image = "MyImage"}
},
Message = "MyMessage",
Title = "MyTitle",
User = new User()
};
using (Context context = new Context(connection))
{
context.Advertisements.Add(ad);
context.SaveChanges();
}
}
在数据库上产生了这个查询
ExecuteDbDataReader==========
insert into [Users]([AccessToken])
values (null);
select [UserId]
from [Users]
where [UserId] = @@identity
ExecuteDbDataReader==========
insert into [Advertisements]([Title], [Message], [User_UserId])
values (@p0, @p1, @p2);
select [Id]
from [Advertisements]
where [Id] = @@identity
@p0 = MyTitle
@p1 = MyMessage
@p2 = 1
ExecuteDbDataReader==========
insert into [AdImages]([Image], [Advertisement_Id])
values (@p0, @p1);
select [Id]
from [AdImages]
where [Id] = @@identity
@p0 = MyImage
@p1 = 1
你的模型简直完美:)
所以问题出在其他地方。
它可能在代码中,周围,即
- model
和user
来自哪里?您在 Upsert 中使用的上下文相同还是不同?
- 你在 Upsert 中做什么?您是否更改了一些引用(从 model
到新对象)?
- 其他缺失的类(我留空的那些)可以吗?
关于c# - 定义实体关系时如何为依赖操作指定有效顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36188603/