엔티티 프레임 워크에 대해 XML
을 사용하고 있습니다. I는 속성 런타임 주입 수도 엔티티의 타입을 만들려고 먼저 I는엔티티 프레임 워크 엔티티가 DataSpace.OSpace (_workspace.GetItemCollection (DataSpace.OSpace))에 없지만 DataSpace.CSpace에 있습니다.
public class DynamicEntity : DynamicObject
{
Dictionary<string, object> dynamicMembers = new Dictionary<string, object>();
public override bool TrySetMember(SetMemberBinder binder, object value)
{
dynamicMembers[binder.Name] = value;
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (dynamicMembers.TryGetValue(binder.Name, out result))
{
return dynamicMembers.TryGetValue(binder.Name, out result);
}
result = "";
return true;
}
}
다음 엔티티이
public partial class QUOTE_HOUSE : DynamicEntity
상속 동적 DynamicEntity
객체를 생성 (그것을 수행 db에서 데이터를 얻은 후 속성을 수동으로 설정할 때 작동하는 것 같습니다.
so based on this mechanism of removing properties XML에 속성을 삽입하는 또 다른 작업을 시도했는데 모든 것이 정상적으로 유지되는 것처럼 보입니다. 적어도 XML이 올바르지 않을 때 일반적으로 수행하는 매핑에는 불필요합니다 (var mappingCollection = new StorageMappingItemCollection(conceptualCollection, storageCollection, new[] {mappingXml.CreateReader()});
). 쿼리를 실행함으로써
엔티티 타입 QUOTE_HOUSE 현재 컨텍스트 모델의 일부가 아닌 경우와 불면
문제 EF이다.
설명 현재 웹 요청 을 실행하는 중 처리되지 않은 예외가 발생했습니다. 오류에 대한 정보와 코드에서 오류가 발생한 위치에 대한 정보는 에 대한 스택 추적을 검토하십시오.
예외 정보 : System.InvalidOperationException : 엔터티 유형 QUOTE_HOUSE가 현재 컨텍스트의 모델에 속해 있지 않습니다.
[InvalidOperationException이 :. 엔티티 타입 QUOTE_HOUSE 가 현재 컨텍스트 모델의 일부가 아니다]
에 대한로드 PDB 후
System.Data.Entity.Internal.InternalContext.UpdateEntitySetMappingsForType (유형 entityType) 208
System.Data. Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType 내가EF
System.Data.Entity.Internal.InternalContext
에TryUpdateEntitySetMappingsForType
추적 (유형 entityType) +50
기본적으로 내 QUOTE_HOUSE
은 this._workspace.GetItemCollection(DataSpace.OSpace)
이 아니며 여기서 UpdateEntitySetMappings
은 매핑을 시도합니다. 이 this._entitySetMappingsCache.ContainsKey(entityType))
에 있다면
그것은 확인하고 그렇지 않은 이후로는 내 엔티티가 this._workspace.GetItems<EntityContainer>(DataSpace.CSpace)
에 존재하는 것을 볼 수있다 그러나 내 항목이
존재하지 않는 경우 this._workspace.GetItemCollection(DataSpace.OSpace)
반복 갱신 매핑을 시도합니다.
전체 UpdateEntitySetMappings
외모 다음
private void UpdateEntitySetMappings()
{
ObjectItemCollection objectItemCollection = (ObjectItemCollection) this._workspace.GetItemCollection(DataSpace.OSpace);
ReadOnlyCollection<EntityType> items = this._workspace.GetItems<EntityType>(DataSpace.OSpace);
Stack<EntityType> entityTypeStack = new Stack<EntityType>();
foreach (EntityType entityType1 in items)
{
entityTypeStack.Clear();
EntityType cspaceType = (EntityType) this._workspace.GetEdmSpaceType((StructuralType) entityType1);
do
{
entityTypeStack.Push(cspaceType);
cspaceType = (EntityType) cspaceType.BaseType;
}
while (cspaceType != null);
EntitySet entitySet = (EntitySet) null;
while (entitySet == null && entityTypeStack.Count > 0)
{
cspaceType = entityTypeStack.Pop();
foreach (EntityContainer entityContainer in this._workspace.GetItems<EntityContainer>(DataSpace.CSpace))
{
List<EntitySetBase> list = entityContainer.BaseEntitySets.Where<EntitySetBase>((Func<EntitySetBase, bool>) (s => s.ElementType == cspaceType)).ToList<EntitySetBase>();
int count = list.Count;
if (count > 1 || count == 1 && entitySet != null)
throw Error.DbContext_MESTNotSupported();
if (count == 1)
entitySet = (EntitySet) list[0];
}
}
if (entitySet != null)
{
EntityType entityType2 = (EntityType) this._workspace.GetObjectSpaceType((StructuralType) cspaceType);
Type clrType1 = objectItemCollection.GetClrType((StructuralType) entityType1);
Type clrType2 = objectItemCollection.GetClrType((StructuralType) entityType2);
this._entitySetMappingsCache[clrType1] = new EntitySetTypePair(entitySet, clrType2);
}
}
}
어떻게 실체는 this._workspace.GetItemCollection (DataSpace.OSpace)로받을 수 있나요? 엔터티가 CSpace
에 있지만 OSpace
에없는 이유는 무엇입니까?
편집 : 현상금에 균열을 가지고 싶어 수있는 사람들을 위해 은, 아래가 설정하는 환경 문제를 재현해야 할 수 있습니다 구성 요소입니다. 엔티티가 DB 제에서 발생
public class SystemToDatabaseMapping
{
public SystemToDatabaseMapping(string system, string databaseType, string database, string connectionString, Type enitityType)
{
System = system;
Database = database;
DatabaseType = databaseType;
ConnectionString = connectionString;
EntityType = enitityType;
}
public Type EntityType { get; set; }
public string System { get; set; }
public string Database { get; set; }
public string DatabaseType { get; set; }
public string ConnectionString { get; set; }
public List<ColumnToModify> ColumnsToModify { get; set; }
}
public abstract class ColumnToModify
{
protected ColumnToModify(string table, string column)
{
Table = table;
Column = column;
}
public string Table { get; set; }
public string Column { get; set; }
public abstract bool IsRemove{ get; }
}
public class ColumnToRemove : ColumnToModify
{
public ColumnToRemove(string table, string column) : base(table, column)
{
}
public override bool IsRemove
{
get { return true; }
}
}
public class ColumnToAdd : ColumnToModify
{
public ColumnToAdd(string table, string column, Type type) : base(table, column)
{
this.Type = type;
}
public override bool IsRemove
{
get { return false; }
}
public Type Type { get; set; }
}
, 데이터베이스
public partial class QUOTE_HOUSE : DynamicEntity
{
public long UNIQUE_ID { get; set; }
}
DbContext 생성자 열 주입 (그렇게 대략 원형의 수행
public partial class EcomEntities : DbContext
{
public EcomEntities(DbConnection connectionString)
: base(connectionString, false)
{
}
public virtual DbSet<QUOTE_HOUSE > QUOTE_HOUSE { get; set; }
....
}
메커니즘 과부하 요구 (DynamicEntity
코드 위이다) 그것이 atm을 보는지 얼마나 나쁜지에 대해 용서하십시오.) try string column을 주입 할 때 나는 그것이 잘 매핑된다는 것을 안다.
public static class EntityConnectionExtensions
{
public static IEnumerable<XElement> ElementsAnyNS<T>(this IEnumerable<T> source, string localName)
where T : XContainer
{
return source.Elements().Where(e => e.Name.LocalName == localName);
}
public static IEnumerable<XElement> ElementsAnyNS(this XContainer source, string localName)
{
return source.Elements().Where(e => e.Name.LocalName == localName);
}
private static void ModifyNodes(XElement element, List<ColumnToModify> tableAndColumn)
{
if (element.Attribute("Name") != null && tableAndColumn.Any(oo => oo.Table == element.Attribute("Name").Value) ||
element.Attribute("StoreEntitySet") != null && tableAndColumn.Any(oo => oo.Table == element.Attribute("StoreEntitySet").Value))
{
var matchingRemoveSelectParts = tableAndColumn.Where(oo => oo.IsRemove && element.Value.Contains(string.Format("\"{0}\".\"{1}\" AS \"{1}\"", oo.Table, oo.Column))).ToList();
if (matchingRemoveSelectParts.Any())
{
foreach (var matchingRemoveSelectPart in matchingRemoveSelectParts)
{
var definingQuery = element.ElementsAnyNS("DefiningQuery").Single();
definingQuery.Value = definingQuery.Value.Replace(string.Format(", \n\"{0}\".\"{1}\" AS \"{1}\"", matchingRemoveSelectPart.Table, matchingRemoveSelectPart.Column), "");
}
}
else
{
var nodesToRemove = element.Nodes()
.Where(o =>
o is XElement
&& ((XElement) o).Attribute("Name") != null
&& tableAndColumn.Any(oo => oo.IsRemove && ((XElement) o).Attribute("Name").Value == oo.Column));
foreach (var node in nodesToRemove.ToList())
{
node.Remove();
}
if (element.Attribute("Name") != null && tableAndColumn.Any(oo => oo.Table == element.Attribute("Name").Value))
{
var elementsToAdd = tableAndColumn.Where(o => !o.IsRemove && o.Table == element.Attribute("Name").Value);
if (new[] {"Type=\"number\"", "Type=\"varchar2\"", "Type=\"date\""}.Any(o => element.ToString().Contains(o)))
{
foreach (var columnToModify in elementsToAdd)
{
var columnToAdd = (ColumnToAdd) columnToModify;
var type = new[] {typeof (decimal), typeof (float), typeof (int), typeof (bool)}.Contains(columnToAdd.Type)
? "number"
: columnToAdd.Type == typeof (DateTime) ? "date" : "varchar2";
var precision = "";
var scale = "";
var maxLength = "";
if (type == "number")
{
precision = "38";
scale = new[] {typeof (decimal), typeof (float)}.Contains(columnToAdd.Type) ? "2" : "0";
}
if (type == "varchar2")
{
maxLength = "500";
}
var newProperty = new XElement(element.GetDefaultNamespace() + "Property", new XAttribute("Name", columnToAdd.Column), new XAttribute("Type", type));
if (!string.IsNullOrWhiteSpace(precision))
{
newProperty.Add(new XAttribute("Precision", precision));
}
if (!string.IsNullOrWhiteSpace(scale))
{
newProperty.Add(new XAttribute("Scale", scale));
}
if (!string.IsNullOrWhiteSpace(maxLength))
{
newProperty.Add(new XAttribute("MaxLength", maxLength));
}
element.Add(newProperty);
}
}
else if (
new[] {"Type=\"Decimal\"", "Type=\"String\"", "Type=\"DateTime\"", "Type=\"Boolean\"", "Type=\"Byte\"", "Type=\"Int16\"", "Type=\"Int32\"", "Type=\"Int64\""}.Any(
o => element.ToString().Contains(o)))
{
foreach (var columnToModify in elementsToAdd)
{
var columnToAdd = (ColumnToAdd) columnToModify;
var type = new[] {typeof (decimal), typeof (float), typeof (int), typeof (bool)}.Contains(columnToAdd.Type)
? "Decimal"
: columnToAdd.Type == typeof (DateTime) ? "DateTime" : "String";
var precision = "";
var scale = "";
var maxLength = "";
if (type == "Decimal")
{
precision = "38";
scale = new[] {typeof (decimal), typeof (float)}.Contains(columnToAdd.Type) ? "2" : "0";
}
if (type == "String")
{
maxLength = "500";
}
var newProperty = new XElement(element.GetDefaultNamespace() + "Property", new XAttribute("Name", columnToAdd.Column), new XAttribute("Type", type));
if (!string.IsNullOrWhiteSpace(precision))
{
newProperty.Add(new XAttribute("Precision", precision));
}
if (!string.IsNullOrWhiteSpace(scale))
{
newProperty.Add(new XAttribute("Scale", scale));
}
if (!string.IsNullOrWhiteSpace(maxLength))
{
newProperty.Add(new XAttribute("MaxLength", maxLength));
newProperty.Add(new XAttribute("FixedLength", "false"));
newProperty.Add(new XAttribute("Unicode", "false"));
}
element.Add(newProperty);
}
}
}
}
if (element.Attribute("Name") != null && tableAndColumn.Any(oo => oo.Table == element.Attribute("Name").Value) && element.GetNamespaceOfPrefix("store") != null &&
element.Attribute(element.GetNamespaceOfPrefix("store") + "Type") != null &&
element.Attribute(element.GetNamespaceOfPrefix("store") + "Type").Value == "Tables")
{
var matchingAddSelectParts = tableAndColumn.Where(o => !o.IsRemove && o.Table == element.Attribute("Name").Value);
foreach (var matchingAddSelectPart in matchingAddSelectParts)
{
var definingQuery = element.ElementsAnyNS("DefiningQuery").Single();
var schemaRegex = new Regex(string.Format("\\nFROM \\\"([a-zA-Z0-9]*)\\\".\\\"{0}\\\"", matchingAddSelectPart.Table));
var schema = schemaRegex.Matches(definingQuery.Value)[0].Groups[1].Value;
definingQuery.Value = definingQuery.Value.Replace(
string.Format("\nFROM \"{0}\".\"{1}\" \"{1}\"", schema, matchingAddSelectPart.Table),
string.Format(", \n\"{0}\".\"{1}\" AS \"{1}\"\nFROM \"{2}\".\"{0}\" \"{0}\"", matchingAddSelectPart.Table, matchingAddSelectPart.Column, schema));
}
}
if (element.Attribute("StoreEntitySet") != null && tableAndColumn.Any(oo => !oo.IsRemove && oo.Table == element.Attribute("StoreEntitySet").Value))
{
var matchingAddSelectParts = tableAndColumn.Where(o => !o.IsRemove && o.Table == element.Attribute("StoreEntitySet").Value);
foreach (var matchingAddSelectPart in matchingAddSelectParts)
{
element.Add(new XElement(element.GetDefaultNamespace() + "ScalarProperty", new XAttribute("Name", matchingAddSelectPart.Column),
new XAttribute("ColumnName", matchingAddSelectPart.Column)));
}
}
}
}
public static EntityConnection Create(List<ColumnToModify> tablesAndColumns, string connString)
{
var modelNameRegex = new Regex(@".*metadata=res:\/\/\*\/([a-zA-Z.]*).csdl|.*");
var model = modelNameRegex.Matches(connString).Cast<Match>().SelectMany(o => o.Groups.Cast<Group>().Skip(1).Where(oo => oo.Value != "")).Select(o => o.Value).First();
var conceptualReader = XmlReader.Create(Assembly.GetExecutingAssembly().GetManifestResourceStream(model + ".csdl"));
var mappingReader = XmlReader.Create(Assembly.GetExecutingAssembly().GetManifestResourceStream(model + ".msl"));
var storageReader = XmlReader.Create(Assembly.GetExecutingAssembly().GetManifestResourceStream(model + ".ssdl"));
var conceptualXml = XElement.Load(conceptualReader);
var mappingXml = XElement.Load(mappingReader);
var storageXml = XElement.Load(storageReader);
foreach (var entitySet in new[] {storageXml, conceptualXml}.SelectMany(xml => xml.Elements()))
{
if (entitySet.Attribute("Name").Value == "ModelStoreContainer")
{
foreach (var entityContainerEntitySet in entitySet.Elements())
{
ModifyNodes(entityContainerEntitySet, tablesAndColumns);
}
}
ModifyNodes(entitySet, tablesAndColumns);
}
foreach (var entitySet in mappingXml.Elements().ElementAt(0).Elements())
{
if (entitySet.Name.LocalName == "EntitySetMapping")
{
foreach (var entityContainerEntitySet in entitySet.Elements().First().Elements())
{
ModifyNodes(entityContainerEntitySet, tablesAndColumns);
}
}
ModifyNodes(entitySet, tablesAndColumns);
}
var storageCollection = new StoreItemCollection(new [] {storageXml.CreateReader()});
var conceptualCollection = new EdmItemCollection(new[] { conceptualXml.CreateReader() });
var mappingCollection = new StorageMappingItemCollection(conceptualCollection, storageCollection, new[] {mappingXml.CreateReader()});
var workspace = new MetadataWorkspace();
workspace.RegisterItemCollection(conceptualCollection);
workspace.RegisterItemCollection(storageCollection);
workspace.RegisterItemCollection(mappingCollection);
var connectionData = new EntityConnectionStringBuilder(connString);
var connection = DbProviderFactories
.GetFactory(connectionData.Provider)
.CreateConnection();
connection.ConnectionString = connectionData.ProviderConnectionString;
return new EntityConnection(workspace, connection);
}
}
초기화 :
public ActionResult QUOTE_HOUSE()
{
var onlineDocs = Enumerable.Empty<QUOTE_HOUSE>();
var mappings = new List<SagaSystemToDatabaseMapping>{new SagaSystemToDatabaseMapping("x", "Oracle", "Db1",
"metadata=res://*/Ecom.Ecom.csdl|res://*/Ecom.Ecom.ssdl|res://*/Ecom.Ecom.msl;provider=Oracle.ManagedDataAccess.Client;provider connection string='...'", typeof(EcomEntities))
{
ColumnsToModify = new List<ColumnToModify> { new ColumnToAdd("QUOTE_HOUSE","TESTCOL", typeof(string)) }
}};
var entityConnection = EntityConnectionExtensions.Create(mappings[0].ColumnsToModify,mappings[0].ConnectionString);
using (var db = new EcomEntities(entityConnection))
{
onlineDocs = db.QUOTE_HOUSE.Take(10);
}
return View("QUOTE_HOUSE", onlineDocs.ToList());
}
당신은 엔티티 QUOTE_HOUSE
에서 오라클 데이터베이스를 생성하고 몇 가지 더미 값을 입력 할 수 있어야한다, 그것은 .ToList()
에 불면 당신이 볼 필요가 있다고 생각하지 않습니다. 데이터베이스를 생성 한 후 데이터베이스에 열을 추가하지만 모델 (alter table QUOTE_HOUSE add TESTCOL Varchar2(20)
)은 추가하지 않습니다. 런타임에 모델에 삽입되는 데이터베이스의 열을 갖습니다. EF assemblies here's how to do it을 디버그해야 할 수도 있습니다. 더 많은 정보가 필요하거나 뭔가를 놓친 경우 알려주십시오.
추가 정보가 필요하거나 환경 설정에 도움이 필요한 사람은 http://chat.stackexchange.com/rooms/41755/ef-hacking을 만들었습니다. –