我正在尝试对包含Advertisement
的List<AdImage>
对象进行Upsert。 Advertisement
包含一个与User
对应的外键。 user
可以具有零个或多个Advertisements
,而Advertisement
可以具有一个或多个AdImages
。
Upsert失败,并显示以下内容:
内在的地方是:
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);
}
错误消息是什么意思?我看不到我的关系定义不正确。我该如何解决?
最佳答案
这只是评论,但我不能在评论中写...
这是我第一次看到异常(exception)
所以我试图重现它。
这是我实现错过的类(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
到新对象)?-其他缺少的类(class)(我留空的类(class))可以吗?