我在使用web api在asp.net中一次更新我的数据库1列时遇到此问题。我试图查询PUT只更新行中的一个值而不是更新那个值并将其余值设置为null。我在控制器之外做了一个单独的模型来接受更新,所以我可以一次做一个。当我在控制器中点击此行db.Entry(user).State = EntityState.Modified;
时,它出错了。有什么建议我怎么解决这个问题?
这是我在put方法中使用的单独的ViewModel:
namespace WebAPI.Models.ViewModels
{
public class UserViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
这是我的控制器在我的参数中使用ViewModel调用方法:
public HttpResponseMessage PutUser(int id, UserViewModel user)
{
HttpResponseMessage response;
if (db.User.IsInRole("Admin"))
{
try
{
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!UserExists(id))
{
response = new HttpResponseMessage(HttpStatusCode.NotFound);
return response;
}
else
{
throw;
}
}
response = new HttpResponseMessage(HttpStatusCode.NoContent);
return response;
}
这是我的DBContext
文件:
public partial class Entities : DbContext
{
public Entities()
: base("name=Entities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<User> Users { get; set; }
}
}
该错误来自您初始化数据上下文db
的方式。
用户对象是在单独的db
中创建的,因此,当您尝试更新user
时,当前的数据库不知道这个user
对象。
您可以通过获取用户来解决它
try
{
// or check on FirstName and LastName if you don't have a user id
var updatedUser = db.Users.SingleOrDefault(x => x.id == id);
updatedUser.FirstName = user.FirstName;
updatedUser.LastName = user.LastName;
db.Entry(updatedUser).State = EntityState.Modified;
db.SaveChanges();
}
或者,您可以确保用于创建user
对象的数据上下文与尝试更新用户的数据上下文相同。
你能理解这个吗?
我遇到过同样的问题。我的问题是我没有放任何映射实体/表。映射我的实体后,问题就解决了。
在我的情况下,问题是相应的实体文件中没有一列。 edmx中有一列映射,但charp文件中没有
如果您的存储库需要动态访问不同的Entity Framework DbContext(这意味着不同的数据库),则总会发生这种情况。
检查web.config文件中的每个Entity Framework DbContext的数据连接字符串。
例如:
<add name="CRMEntities" connectionString="metadata=res://*/CRMEntities.csdl|res://*/CRMEntities.ssdl|res://*/CRMEntities.msl;provider=System.Data.SqlClient;provider connection string="data source=Your Data Source;initial catalog=CRM;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
检查connectionString中的元数据是否指向正确的DbContext。
在此示例中,它指向名为“CRMEntities”的demx文件。
确保您具有正确的元数据部分应与edmx中的相同。
connectionString="metadata=res://*/Model1.csdl|res://*/Model1.ssdl|res://*/Model1.msl;"
更新模型以包含ID属性。
然后做
var e = db.Entry(user);
e.Property(p => p.FirstName).Modified = true;
属性行是指定单个字段的方式。
您的viewmodel不是完全限定的User对象。因此,您需要获得一个。
此调用db.User.IsInRole("Admin")
似乎表明您已拥有当前用户。您应该只修改那个,然后提交更改
try
{
db.User.FirstName = user.FirstName;
db.User.LastName = user.LastName;
db.Entry(db.User).State = EntityState.Modified;
db.SaveChanges();
}
我也得到了这个例外。我通过右键单击图中的Entity.edmx模型并通过“从数据库更新模型”刷新与数据库的连接来解决它。
我不知道为什么会这样,但至少在我的情况下确实如此。
这发生在我身上,因为有人通过剪切和粘贴来自现有的app.config中创建了一个新的连接字符串。
结果看起来像这样:
<connectionStrings>
<add
name="Db1Context"
connectionString="metadata=res://*/Db1Context.csdl|res://*/Db1Context.ssdl|res://*/Db1Context.msl;..."
providerName="System.Data.EntityClient"
/>
<add
name="Db2Context"
connectionString="metadata=res://*/Db1Context.csdl|res://*/Db1Context.ssdl|res://*/Db1Context.msl;..."
providerName="System.Data.EntityClient"
/>
</connectionStrings>
注意Db2Context如何在其元数据中引用DbContext1 ...
验证服务器是64位还是32位并重新编译应用程序。
当我尝试将我的类的实例添加到DbSet时,我遇到了同样的问题。我的问题是数据库中表的定义与我的acutal对象不匹配(我的模型中缺少2个非null属性)。我将两个属性添加到我的类中,错误消失了。