2012-09-10 39 views
0

所以我得到了2个数据库,1个SQLite文件,每周更新一次(所以我需要每周运行一次这个更新)。和一个SQLserver(但现在使用SQLfile仅用于本地测试等)。不过,我正在寻找一种简单的方法来将SQLite文件中的所有数据复制到SQLserver,就像10个类一样,它们都存在于两个数据库中,但sqlite在sqlserver的开始时没有首字母大写。从其他数据库导入其他属性名称的数据

在sqlite中有一个带有id,name和lastname的人表。在SQLserver上,该表称为Person(具有大写字母),列是Id Name和Lastname。 SQlite文件由第三方提供,我无法决定他们做什么。 SQLserver由Code First EF制作。 (并且我把这一切都归咎于CamelCase)。

有没有简单的方法来复制所有的数据,我正在寻找类的属性循环,然后降低例如。

ForEach(var person in SQLiteDB.persons) 
{ 
    Person thenewperson = new Person(); 
    foreach (var prop in person.GetType().GetProperties()) 
    { 
     // Here I get stuck I want something like 
     if(thenewperson.Haspropertie.ToLower(prop.GetName.ToLower) // This is incorrect but I think you ll understand if we do a ToLower then we can get it to work. Since only capitals are the things that are different. 
     { 
      //Then we copy the data to "thenewperson" 
     } 

    } 
    SQlserverDB.Persons.AddorUpdate(thenewperson) // Not totaly correct but you get the point. 
} 

我不知道或者我会在正确的方向,我用Google搜索上如何循环特性,但在寻找复制数据的好办法没有运气。我也因为尝试修复VS 2012与SQLite一起工作而感到头疼,但ADO.net似乎不起作用,所以我不得不再次安装VS2010等等lol(现在都运行)。

希望有人对此有一个很好的解决方案,如果你有任何问题随时问。

编辑:我忘了提及它也有导航propertys。 (如PersonAbilitys)。这也需要被复制

回答

1

这应该做你正在尝试(未测试,也许失败)内容:

foreach(var person in SQLiteDB.persons) 
{ 
    Person thenewperson = new Person(); 
    foreach (var prop in person.GetType().GetProperties()) 
    { 
     var newPersonProp = thenewperson.GetType().GetProperties() 
                .FirstOrDefault(p => p.Name.ToLower() == prop.Name.ToLower()); 

     if (newPersonProp != null) 
     { 
      newPersonProp.SetValue(thenewperson, prop.GetValue(person, null), null); 
     } 
    } 
    SQlserverDB.Persons.AddorUpdate(thenewperson); // Not totaly correct but you get the point. 
}

但是,您可以通过预先计算的属性映射改进它,所以你不必须为每个SQLiteDB.persons查找它。

var propertyMapping = new Dictionary<PropertyInfo, PropertyInfo>(); 
var efPersonType = typeof(Person); 
var sqlitePersonType = typeof(SQLLitePerson); 

foreach (var prop in sqlitePersonType.GetProperties()) 
{ 
    var efProp = efPersonType.GetProperties() 
          .FirstOrDefault(p => p.Name.ToLower() == prop.Name.ToLower()); 
    if (efProp != null) 
    { 
     propertyMapping.Add(prop, efProp); 
    } 
} 

foreach (var person in SQLiteDB.persons) 
{ 
    Person thenewperson = new Person(); 
    foreach (var i in propertyMapping) 
    { 
     i.Value.SetValue(thenewperson, i.Key.GetValue(person, null), null); 
    } 
    SQlserverDB.Persons.AddorUpdate(thenewperson); 
} 

还可以拾取对象映射器,例如AutoMapper。然后,您可以创建自定义约定来使其工作。

如果你有更复杂的实体,那么你应该去AutoMapper而不是滚动您自己的映射解决方案,以节省自己的时间:AutoMapper Wiki

顺便说一句最简单的方法来做到这一点是建立手写映射。

+0

感谢您的快速回复,但我认为它会很好,直到我收藏。 'System.Data.Objects.DataClasses.EntityCollection'1 [DataImport.personAbility]'类型的对象无法转换为类型'System.Data.Objects.DataClasses.EntityCollection'1 [DataImport.PersonAbility – Maximc

+0

我不知道你在你的类中有导航属性。这使故事变得复杂。 –

+0

对不起忘了提到它,这是否使这非常复杂:/? – Maximc