如何获取Entity Framework 6.1中所有实体关系的列表?

时间:2016-06-28 22:40:02

标签: c# entity-framework entity-framework-6 entity relation

我正在尝试获取所有关系列表"外键"以编程方式在模型上(键,相关对象,外部列名称。)

我发现this other question似乎在做同样的事情。但我无法得到答案的代码为我工作。

这就是我所做的

    public List<string> GetObjectRelations(Type type)
    {

        var metadata = ((IObjectContextAdapter)this.context).ObjectContext.MetadataWorkspace;

        // Get the part of the model that contains info about the actual CLR types
        var objectItemCollection = ((ObjectItemCollection)metadata.GetItemCollection(DataSpace.OSpace));

        var fk = metadata.GetItems<AssociationType>(DataSpace.CSpace).Where(a => a.IsForeignKey);

        //check if the table has any foreign constraints for that column
        var fkname = fk.Where(x => x.ReferentialConstraints[0].ToRole.Name == type.Name).Where(x => x.ReferentialConstraints[0].ToProperties[0].Name == type.Name);

        //Get the corresponding reference entity column name
        return fkname.Select(x => x.ReferentialConstraints[0].FromProperties[0].Name).ToList();

    }

以下是我如何称呼此方法

var relations = QueryExtractor.GetObjectRelations(typeof(TSource)); 

但是这段代码对我不起作用。返回值为空。

如何正确获取外键及其相关对象?

已更新

以下是我目前基于muratgu答案的代码。但它现在仍然给我一个关系列表

    public List<Dictionary<string, object>> GetObjectRelations(Type type)
    {
        var relations = new List<Dictionary<string, object>>();

        var metadata = ((IObjectContextAdapter)this.context).ObjectContext.MetadataWorkspace;

        var fk_all = metadata.GetItems<AssociationType>(DataSpace.CSpace).Where(a => a.IsForeignKey);

        var fk_out = fk_all.Where(x => x.ReferentialConstraints[0].ToRole.Name == type.Name).ToList(); // relations going out 

        foreach (var fk in fk_out)
        {
            var relation = new Dictionary<string, object>();

            var fk_ref = fk.ReferentialConstraints[0]; //How can a foreign key relation have more than one column?

            var objectName = fk_ref.FromRole.Name;

            var attributeName = fk_ref.FromProperties[0].Name;

            relation.Add(objectName, attributeName);

            relations.Add(relation);
        }

        return relations;
    }

2 个答案:

答案 0 :(得分:1)

你已经在代码片段中拥有了所需的一切,尽管我有一种预感,即返回一个字符串列表对你来说是不够的。我会将其分解,以便您可以决定如何处理结果。

        // assume Child has a foreign key (Parent_Id) to Parent (Id)
        // assume primary keys are not composite
        var type = typeof(Child); 
        var fk_all = metadata.GetItems<AssociationType>(DataSpace.CSpace).Where(a => a.IsForeignKey);
        var fk_out = fk_all.Where(x => x.ReferentialConstraints[0].ToRole.Name == type.Name).ToList(); // relations going out 
        foreach(var fk in fk_out) { // could be many
            var fk_ref = fk.ReferentialConstraints[0]; // what if more than one?
            Console.WriteLine("From {0} - {1} ", fk_ref.FromRole.Name, fk_ref.FromProperties[0].Name);
            Console.WriteLine("To {0} - {1} ", fk_ref.ToRole.Name, fk_ref.ToProperties[0].Name);
        }

假设Child有一个外键Parent_IdParentId),则会打印出来:

        From Parent - Id
        To Child - Parent_Id

答案 1 :(得分:0)

根据this answer,您可以使用Entity Framework Mapping Api Extensions。例如,以下行检索产品类型的外键:

string[] fks = context.Db<Product>().Fks.Select(fk => fk.PropertyName).ToArray();