ado.net entity framework无法更新数据库

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ado.net entity framework无法更新数据库相关的知识,希望对你有一定的参考价值。

想向表中新增一条记录,add后,savechanges(),datagridview确实增加的数据,但是数据库里面没增加。困扰了两天不得解决,也没有报错和抛出异常用的SQL SERVER 2008

楼上两位可能不懂Entity Framework!这就是大名远播的EF,据说想扔掉linq to sql的原因就是EF.

首先不管是EF还是linq to sql都是ORM,但是Linq to sql从名称上你就知道它仅仅是为了一个SQL server(只能连接SQL server),至少在设计时是这样的。

但是EF的目换就是不在乎下层数据库是谁了!如果是从sql中来的,那和连接字符串其他是连接好的。如果没有,那么他也没有进行连接——事实上你可以让EF自行生成SQL,并在EF设计中连接数据库并执行的!

从面向对象设计角度来说,EF与数据库的关系更加松散,已经消除了与数据库的藕合,也是以后多数据设计下的一种选择。但是,ORM只是ORM(对象关系映射),它只是中间的一个层,他将数据库数据映射为程序中的对象,就这么一个做用,如果你没有连接数据库的情况下,数据持久不会发生,也就是说,Datagridview得到的是ORM中间的数据,在DGV中存在并不代表已经持久到数据库,所以还是建议你从连接入手,查询相关问题。追问

MSDN例程里面没找到还要手动连接数据库的,在savechanges()调用后还要如何连接,请给个具体的例子

追答

如果你是建立ef时,不要选择空库,即使用选择空库时在选择连接时要选定一个连接,并明文保存。如果没有明文保存时,则在SchoolContext schoolCotext = new SchoolContext(连接字符串,一般可在配置文件);

这样你的字符串就连接上了。如果空的情况会报错。

总之必须是在运行时连接到数据库上,这是必须的。

建议你断点到SchoolContext语句上,查看该连接字符——SchoolContext.Connection即可看到连接,若不存在连接是绝对无法持久到数据库上的!你可以HI我,我教你怎么玩EF的——好象对于EF你还是新手?!

参考技术A ado.net entity framework无法更新数据库
首先不管是EF还是linq to sql都是ORM,但是Linq to sql从名称上你就知道它仅仅是为了一个SQL server(只能连接SQL server),至少在设计时是这样的。

但是EF的目换就是不在乎下层数据库是谁了!如果是从sql中来的,那和连接字符串其他是连接好的。如果没有,那么他也没有进行连接——事实上你可以让EF自行生成SQL,并在EF设计中连接数据库并执行的!
参考技术B 是不是没有提交,你用到事物了吗?追问

savechanges()不就是提交了么我看MSDN上面都是savechanges()然后就写入数据库了,没用到事物

追答

把你提交DB的代码粘出来看看吧

参考技术C 代码贴出来!追问

Course course = new Course();

course.CourseID = 1;
course.Credits = 1;
course.DepartmentID = 1;
course.Title = "test2";
schoolContext.Courses.AddObject(course);
schoolContext.SaveChanges();

追答

连接字符串 贴出来。

追问

没有连接字符串直接用工具从数据生成的实体模型

ADO.NET Entity Framework 和标识列

【中文标题】ADO.NET Entity Framework 和标识列【英文标题】:ADO.NET Entity Framework and identity columns 【发布时间】:2010-09-12 08:30:58 【问题描述】:

实体框架是否知道标识列?

我使用的是 SQL Server 2005 Express Edition,并且有几个表,其中主键是标识列。当我使用这些表创建实体模型并将模型与实体数据源结合使用以创建新实体时,我被要求为标识列输入一个值。有没有办法让框架不要求标识列的值?

【问题讨论】:

【参考方案1】:

我知道这篇文章已经很老了,但这可能有助于下一个到达的人通过 Google 搜索“实体框架”和“身份”来听到。

似乎 Entity Frameworks 确实尊重服务器生成的主键,如果设置了“Identity”属性就是这种情况。但是,应用程序端模型仍然需要在 CreateYourEntityHere 方法中提供主键。此处指定的键在 SaveChanges() 调用上下文时被丢弃。

here 页面提供了有关此的详细信息。

【讨论】:

【参考方案2】:

这是我见过的最好的答案。您必须手动编辑存储层 xml 以在每个 UniqueIdentifier 类型的主键上设置 StoreGeneratedPattern="Identity",其默认值设置为 NewID()

http://web.archive.org/web/20130728225149/http://leedumond.com/blog/using-a-guid-as-an-entitykey-in-entity-framework-4/

【讨论】:

看了这个建议后,我发现添加了一个丢失的标识,但是EF需要删除并刷新实体数据模型中的对象来修复所有问题。【参考方案3】:

如果您使用的是 Entity Framework 5,则可以使用以下属性。

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]

【讨论】:

【参考方案4】:

在 C# 中,你可以做这样的事情来让它知道:

在你的FooConfiguration.cs : EntityTypeConfiguration<Foo>:

this.Property(x => x.foo).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

然后要使用它,只需确保将项目插入上下文并在使用x.foo 之前调用context.SaveChanges() 以获取更新的自动递增值。否则x.foo 将只是 0 或 null。

【讨论】:

【参考方案5】:

对我有用的是将 StoreGeneratedPattern 设置为 None,当它是一个 Identity 列时。现在一切正常。这样做的主要问题是,如果您有很多模型,那么编辑模型是一件非常麻烦的事情。

【讨论】:

【参考方案6】:

我不敢相信。智能感知 ItemCollection 在 SaveChanges 后生成 ID = 0 的单个项目。

            Dim ItemCollection = From d In action.Parameter
            Select New STOCK_TYPE With 
                        .Code = d.ParamValue.<Code>.Value,
                        .GeneralUseID = d.ParamValue.<GeneralUse>.Value,
            


            GtexCtx.STOCK_TYPE.AddObject( ItemCollection.FirstOrDefault)
            GtexCtx.SaveChanges()

不管我做什么。 8 小时后,包括删除我的模型、35 次构建和重建、试验和编辑 EDMX 的 XML,现在几乎要删除我的整个 SQL Server 数据库。在第 36 次编译时,这个令人瞠目结舌的解决方案奏效了

            Dim abc = ItemCollection.FirstOrDefault
            GtexCtx.STOCK_TYPE.AddObject(abc)
            GtexCtx.SaveChanges()

abc.ID yield 41(我需要的身份)

编辑:这是一个简单的代码,用于循环 AddObject 并仍然获得 ID

Dim listOfST As List(Of STOCK_TYPE) = ItemCollection.ToList()
      For Each q As STOCK_TYPE In listOfST 
         GtexCtx.STOCK_TYPE.AddObject(q)
      Next
 GtexCtx.SaveChanges()

...more code for inter-relationship tables

在 SaveChanges 之后尝试 Intellisence listOfST,您会发现更新的 ID。也许有更好的方法,但概念就在那里

【讨论】:

【参考方案7】:

由于某种原因,实体框架不能完全理解身份。正确的解决方法是将该列的 Setter 设置为 Private。这将使任何生成的 UI 明白它不应该设置标识值,因为它不可能设置私有字段。

【讨论】:

在这种情况下,您将无法通过键编辑实体,因为更新后的对象的值为 0,并且您无法保存更新的更改,因为您找不到对象通过密钥在集合中。 (本案例适用于MVC)【参考方案8】:

如果在你扯掉头发之前一切都失败了 - 尝试删除你的 EntityModel 并从 SQL Server 重新导入。如果您一直在调整键和关系并依赖“从数据库更新模型”功能,那么在我发现的 RC 版本中它仍然存在一些错误 - 新的导入可能会有所帮助。

【讨论】:

这在 7 年后仍然成立。刷新没有收到我的密钥更改。创建一个新模型解决了这个问题。【参考方案9】:

您应该设置标识列的标识规范,以便将 (Is Identity) 属性设置为 true。您可以在 SSMS 的表设计器中执行此操作。那么您可能需要更新实体数据模型。

也许你所说的“主键是一个标识列”是什么意思,或者你错过了这一步。

【讨论】:

【参考方案10】:

Entity Framework 知道并且可以处理标识列。

您的问题可能不是 EF 本身,而是它生成的表单视图。尝试从插入表单中删除标识列的输入,看看会发生什么。

【讨论】:

以上是关于ado.net entity framework无法更新数据库的主要内容,如果未能解决你的问题,请参考以下文章

ADO.NET Entity Framework 和 NHibernate - 何时使用其中之一

ADO.NET Entity Framework 的实际好处是啥?

ADO.NET Entity Framework 如何查看T

ADO.NET Entity Framework 和标识列

ado.net entity framework无法更新数据库

C#ADO .Net Entities Framework在WPF TreeView中的应用