C# 具有前缀实体框架的表的自定义约定

C# 具有前缀实体框架的表的自定义约定,c#,entity-framework,ef-code-first,C#,Entity Framework,Ef Code First,我所有的POCO类都有两个字母前缀LK_3;。主键和外键的实体框架约定不起作用。考虑到我有大约200个类要用Key或ForeignKey属性装饰,这是一个繁琐的过程&听起来不是一个明智的做法 你能推荐一下海关惯例吗 public class LK_Employee { public Guid EmployeeID {get; set;} public string Name {get; set;} } public class LK_Company { pu

我所有的POCO类都有两个字母前缀LK_3;。主键和外键的实体框架约定不起作用。考虑到我有大约200个类要用Key或ForeignKey属性装饰,这是一个繁琐的过程&听起来不是一个明智的做法

你能推荐一下海关惯例吗

public class LK_Employee
{
    public Guid EmployeeID {get; set;}
    public string Name {get; set;}      
}

public class LK_Company
{
    public Guid CompanyID {get; set;}
    public string Name {get; set;}      
}

public class LK_Employee_LK_Company
{
    public Guid EmployeeID {get; set;}      
    public Guid CompanyID{get; set;}        
}

当存在一个简单的列键时,这会将任何类似
LK_TableName
的字段设置为表的主键:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Properties<Guid>()
        .Where(p => "LK_" + p.Name == p.DeclaringType.Name + "Id")
        .Configure(p => p.IsKey());
}
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
modelBuilder.Properties()
.Where(p=>“LK_u”+p.Name==p.DeclaringType.Name+“Id”)
.Configure(p=>p.IsKey());
}
要支持复合关键点以及简单kesy,您需要执行以下操作:

// Counter: keeps track of the order of the column inside the composite key
var tableKeys = new Dictionary<Type,int>();

modelBuilder.Properties<Guid>()
.Where(p =>
{
    // Break the entiy name in segments
    var segments = p.DeclaringType.Name.Split(new[] {"LK_","_LK_"},
                      StringSplitOptions.RemoveEmptyEntries);
    // if the property has a name like one of the segments, it's part of the key
    if (segments.Any(s => s + "ID" == p.Name))
    {
        //  If it's not already in the column counter, adds it
        if (!tableKeys.ContainsKey(p.DeclaringType))
        {
            tableKeys[p.DeclaringType] = 0;
        }
        // increases the counter
        tableKeys[p.DeclaringType] = tableKeys[p.DeclaringType] + 1;
        return true;
    }
    return false;
})
.Configure(a =>
{
    a.IsKey();
    // use the counter to set the order of the column in the composite key
    a.HasColumnOrder(tableKeys[a.ClrPropertyInfo.DeclaringType]);
});
//计数器:跟踪复合键中列的顺序
var tableKeys=新字典();
modelBuilder.Properties()
.其中(p=>
{
//将实体名称分段
var segments=p.DeclaringType.Name.Split,
StringSplitOptions.RemoveEmptyEntries);
//如果属性的名称类似于某个段,则它是键的一部分
if(segments.Any(s=>s+“ID”==p.Name))
{
//如果它不在列计数器中,则添加它
如果(!tableKeys.ContainsKey(p.DeclaringType))
{
tableKeys[p.DeclaringType]=0;
}
//增加计数器
tableKeys[p.DeclaringType]=tableKeys[p.DeclaringType]+1;
返回true;
}
返回false;
})
.Configure(a=>
{
a、 IsKey();
//使用计数器设置组合键中列的顺序
a、 HasColumnOrder(表键[a.ClrPropertyInfo.DeclaringType]);
});

创建外键的约定要复杂得多。您可以通过以下途径查看EF6约定:
/src/EntityFramework.Core/Metadata/Conventions/Internal/ForeignKeyPropertyDiscoveryConvention.cs
,on。有关使用说明,请参见测试:
/test/EntityFramework.Core.tests/Metadata/ModelConventions/ForeignKeyPropertyDiscoveryConventionTest.cs

LK_EmployeeId应该起作用,否?在“多对多桥接表”中定义FK和主键的规则是什么?如果你解释一下,也许我可以为你提出一个解决方案。谢谢。对于键属性,我没有保留任何前缀。例如,LK_Employee表的Id或EmployeeId,有什么建议吗?此代码检查“LK_”+PropertyName=EntityName+“Id”。如果是这样,那就是关键。我还没有找到复合键的解决方案。@Abhijeet我已经更新了我的答案以支持复合键。使用您的实体进行测试。请注意,在您的示例中,您显示的是“ID”,在示例中,您显示的是“ID”。此代码对密钥敏感,但您可以轻松地更改它。