如果我只有entitysetname和唯一属性的值,有没有办法从上下文中获取对象?

时间:2012-12-25 22:18:09

标签: c# entity-framework-5

我正在尝试编写同步过程。我有一个关于我对本地数据库的更改的日志表,并希望将它们应用到远程数据库。

对于每个日志条目,我需要在远程数据库中找到相应的记录,因为我知道实体集名称和名为RowId的唯一字段的值。 RowId不是主键。

我已经尝试将以下内容放在我的上下文类中,但这意味着每次添加新域类时都必须编辑代码。

有没有办法在不使用巨型switch语句的情况下编写程序? 我是一个类似于Entity Framework的GetObjectByKey方法

的方法

这是我要替换的巨型开关语句

public object GetObjectByRowId(string EntitySetName, Guid RowId)
{
    switch ("People")
    {
        case AppDataEnum.People:
            return People.SingleOrDefault(x => x.RowId == RowId);
            break;

等。

我或许可以通过让所有实体实现IRowId接口来解决它,但我希望EF具有内置方式

我问了一个相关的问题here

我认为答案here可能有所帮助。虽然在那种情况下,许多类型都是从同一个表中提取的。在我的场景中,许多表都有RowId字段。

Public Class Person : LoggedEntity
{
 public string FirstName { get; set; }
 public string LastName { get; set; }
}

公共类组织:LoggedEntity     {      public string FirstName {get;组; }      public string LastName {get;组; }     }

Public Class LoggedEntity
{  [Key]
    public int Id { get; set; }
    public Guid RowId { get; set; }
}

2 个答案:

答案 0 :(得分:1)

在这种情况下,您的唯一键包含一个类型+唯一标识符的元组。如果我正确理解你的问题,那么每个给定类型的行ID都是唯一的,但是两个不同类型的对象可能具有相同的行ID。

您可以覆盖GetHashCode并根据类型和行ID的组合构造唯一的哈希。如何提出一个好的哈希函数超出了这个问题的范围,但作为一个非常愚蠢的解决方案,你可以做一些像(Type.Name + RowId).GetHashCode()

这将返回从两个连接的字符串的哈希码。从那时起,您可以将所有内容放在HashSet中并有效地检索对象。

如果不考虑效率,只需在自己的列表中跟踪每种类型的对象,并在查找特定类型时,只需迭代具有感兴趣类型的对象列表,查找特定的RowId。

答案 1 :(得分:0)

在认识到Generics的答案后,我终于得到了

    public TEntity GetEntityByRowId<TEntity>( Guid rowId) where TEntity : LoggedEntity
    {
        return Db.Set<TEntity>().SingleOrDefault(x => x.RowId == rowId);
    }