C# 在ASP.NET MVC with Entity Framework中,在此上下文中仅支持基元类型或枚举类型
我正在创建一个示例ASP.NET MVC web应用程序,并遵循数据库的代码优先方法。我想创建C# 在ASP.NET MVC with Entity Framework中,在此上下文中仅支持基元类型或枚举类型,c#,asp.net,asp.net-mvc,entity-framework,asp.net-mvc-5,C#,Asp.net,Asp.net Mvc,Entity Framework,Asp.net Mvc 5,我正在创建一个示例ASP.NET MVC web应用程序,并遵循数据库的代码优先方法。我想创建产品表和事务表,另外我还想通过迁移包含一些示例数据,但当我尝试执行更新数据库时,我收到了标题中提到的错误消息。我确切地知道错误发生的原因,这是因为我使用了List,如下所示。但是,我不知道如何解决这个问题,而交易应该包括一个或多个产品。我的代码段可以在下面找到 public class Product { public int ProductID { get; set; } publi
产品
表和事务
表,另外我还想通过迁移包含一些示例数据,但当我尝试执行更新数据库
时,我收到了标题中提到的错误消息。我确切地知道错误发生的原因,这是因为我使用了List
,如下所示。但是,我不知道如何解决这个问题,而交易应该包括一个或多个产品。我的代码段可以在下面找到
public class Product
{
public int ProductID { get; set; }
public string Name { get; set; }
}
public class Transaction
{
public int TransactionID { get; set; }
public List<Product> Products { get; set; }
}
最后,保存迁移的Configuration.cs
文件如下所示:
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
protected override void Seed(MyApp.Models.ApplicationDbContext context)
{
var pr = new List<Product>();
pr.Add(new Product { Name = "Book" });
pr.Add(new Product { Name = "Table" });
pr.Add(new Product { Name = "Chair" });
pr.ForEach(i => context.Products.AddOrUpdate(p => p.Name, i));
context.SaveChanges();
context.Transactions.AddOrUpdate(
t => t.Products,
new Transaction { Products = new List<Product>(pr.Where(p => p.Name == "Book" || p.Name == "Table")) },
new Transaction
{
Products = new List<Product>(pr.Where(p => p.Name == "Chair" || p.Name == "Book" || p.Name == "Table"))
}
);
context.SaveChanges();
}
公共配置()
{
AutomaticMiggerationsEnabled=真;
AutomaticMigrationDataLossAllowed=true;
}
受保护的覆盖无效种子(MyApp.Models.ApplicationDbContext上下文)
{
var pr=新列表();
pr.Add(新产品{Name=“Book”});
pr.Add(新产品{Name=“Table”});
pr.Add(新产品{Name=“Chair”});
pr.ForEach(i=>context.Products.AddOrUpdate(p=>p.Name,i));
SaveChanges();
context.Transactions.AddOrUpdate(
t=>t.产品,
新事务{Products=新列表(pr.Where(p=>p.Name==“Book”| | p.Name==“Table”)},
新交易
{
产品=新列表(pr.Where(p=>p.Name==“椅子”| | p.Name==“书本”| | p.Name==“表格”))
}
);
SaveChanges();
}
问题是AddOrUpdate
方法的第一个参数,即identifierExpression
。您应该在那里提供一个基元类型,它确定您希望何时更新以及何时添加。如果数据库中的某一行与identifierExpression
匹配,它将使用您提供的新行进行更新。如果没有,新的将被插入到数据库中
您使用了t.Products
作为标识符,这意味着,当您添加的产品与某个数据库行的Products
相同时,应该进行更新,这是不正确的,因为Products
没有基元类型。因此,您可以提供一个基元类型属性,或者根本不使用此参数(这意味着将插入所有项)
另一方面,如果要将延迟加载添加到模型中,则应将
事务的产品
属性声明为虚拟
现在,更新数据库
成功,但在我的事务
表中,我只有事务ID
,而没有产品
列。它还在products
表中创建了一个新列,名为Transaction\u TransactionID
,其值也不太正确。我希望transaction
表包含TransactionID
和用于该特定事务的产品列表。有什么想法吗?请参阅我添加的建议。当我在我的ApplicationDbContext
中添加该函数时,我会在updatedatabase
或任何其他与迁移和数据库相关的命令上收到多个错误。其中一个错误是“IdentityUserRole::EntityType'IdentityUserRole'未定义键。请定义此EntityType的键”。请尝试将属性设置为虚拟,并使用ICollection
而不是列表
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
}
protected override void Seed(MyApp.Models.ApplicationDbContext context)
{
var pr = new List<Product>();
pr.Add(new Product { Name = "Book" });
pr.Add(new Product { Name = "Table" });
pr.Add(new Product { Name = "Chair" });
pr.ForEach(i => context.Products.AddOrUpdate(p => p.Name, i));
context.SaveChanges();
context.Transactions.AddOrUpdate(
t => t.Products,
new Transaction { Products = new List<Product>(pr.Where(p => p.Name == "Book" || p.Name == "Table")) },
new Transaction
{
Products = new List<Product>(pr.Where(p => p.Name == "Chair" || p.Name == "Book" || p.Name == "Table"))
}
);
context.SaveChanges();
}
context.Transactions.AddOrUpdate(
//t => t.Products, //comment this
new Transaction {
Products = new List<Product>(
pr.Where(p => p.Name == "Book" || p.Name == "Table"))
},
new Transaction
{
Products = new List<Product>(
pr.Where(p => p.Name == "Chair" || p.Name == "Book" || p.Name == "Table"))
}
);
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Transaction>().HasMany(x => x.Products).WithMany();
}