我使用实体框架1与。net 3.5。
我做的事情很简单,就像这样:
var roomDetails = context.Rooms.ToList();
foreach (var room in roomDetails)
{
room.LastUpdated = DateTime.Now;
}
当我尝试这样做时,我得到这个错误:
context.SaveChanges();
我得到了错误:
无法更新EntitySet -因为它有一个DefiningQuery,并且<ModificationFunctionMapping>元素中没有<UpdateFunction>元素来支持当前操作。
我在上下文上做了很多更新,没有任何问题,只有当我试图更新这个特定的实体时。
我所有的搜索结果都是一样的,我要更新的实体上没有声明主键。但是,唉,我有一个主键声明…
I found the original answer of updating the .edmx file work best in my situation. I just wasn't too happy about altering the model every time it was updated from the database. That's why I wrote an additional Text Template file, that is automaticaly invoked when after the model has changed - just like the entities are newly generated. I post it here in this comment.
To make it work, make sure you name it like {model name}.something.tt, and store it in the same folder as your .edmx folder. I named it {model name}.NonPkTables.tt. It does not generate a file on its own due to the invalid file extension definition in the second line. Feel free to use.
<#@ template language="C#" debug="false" hostspecific="true"#>
<#@ output extension="/" #>
<#@ assembly name="System.Core" #>
<#@ assembly name="System.Data" #>
<#@ assembly name="System.Windows.Forms" #>
<#@ assembly name="System.Xml" #>
<#@ assembly name="System.Xml.Linq"#>
<#@ assembly name="%VS120COMNTOOLS%..\IDE\EntityFramework.dll" #>
<#@ assembly name="%VS120COMNTOOLS%..\IDE\Microsoft.Data.Entity.Design.dll" #>
<#@ import namespace="System" #>
<#@ import namespace="System.Windows.Forms" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Xml" #>
<#@ import namespace="System.Xml.Linq" #>
<#@ import namespace="System.Globalization" #>
<#@ import namespace="System.Reflection" #>
<#@ import namespace="System.Data.Entity.Core.Metadata.Edm" #>
<#@ import namespace="System.Data.Entity.Core.Mapping" #>
<#@ import namespace="System.CodeDom" #>
<#@ import namespace="System.CodeDom.Compiler" #>
<#@ import namespace="Microsoft.CSharp"#>
<#@ import namespace="System.Text"#>
<#@ import namespace="System.Diagnostics" #>
<#
string modelFileName= this.Host.TemplateFile.Split('.')[0] + ".edmx";
string edmxPath = this.Host.ResolvePath( modelFileName );
// MessageBox.Show( this.Host.TemplateFile + " applied." );
var modelDoc = XDocument.Load(edmxPath);
var root = modelDoc.Root;
XNamespace nsEdmx = @"http://schemas.microsoft.com/ado/2009/11/edmx";
XNamespace ns = @"http://schemas.microsoft.com/ado/2009/11/edm/ssdl";
var runtime = root.Elements(nsEdmx + "Runtime").First();
var storageModels = runtime.Elements(nsEdmx + "StorageModels").First();
XNamespace nsStore = @"http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator";
var schema = storageModels.Elements(ns + "Schema").First();
XNamespace nsCustomAnnotation = @"http://schemas.microsoft.com/ado/2013/11/edm/customannotation";
var entityTypes = schema.Nodes().OfType<XComment>().Where(c => c.Value.Contains("warning 6002: The table/view"));
bool changed = false;
foreach (var node in entityTypes)
{
var element = node.ElementsAfterSelf().First();
string entityName = element.Attribute("Name").Value;
// Find EntitySet in EntityContainer.
var entityContainer = schema.Elements(ns + "EntityContainer").First();
var entitySet = entityContainer.Elements(ns + "EntitySet").First(s => s.Attribute("Name").Value == entityName);
// Change "store:Schema" attribute to "Schema" attribute.
var attribute = entitySet.Attribute(nsStore + "Schema");
if (attribute != null)
{
string schemaName = entitySet.Attribute(nsStore + "Schema").Value;
entitySet.Attribute(nsStore + "Schema").Remove();
entitySet.Add(new XAttribute("Schema", schemaName));
changed |= true;
}
// Remove the DefiningQuery element.
var definingQuery = entitySet.Element(ns + "DefiningQuery");
if (definingQuery != null)
{
definingQuery.Remove();
changed |= true;
Debug.WriteLine(string.Format("Removed defining query of EntitySet {0}.", entityName));
}
}
if (changed)
modelDoc.Save(edmxPath);
#>