2014-10-31 71 views
0

我正在开发一个asp.net应用程序。用户可以上传一个csv文件,每行由3个字段组成,姓氏,年龄。我也有一个oracle数据库,我有一个由名字,姓氏,年龄,国家组成的表格。在csv的每一行,我必须在我的表格中检查姓名是否在我的表格中注册。所以它在性能方面非常昂贵。由于我的表只是每晚更新,我正在考虑在.net集合中像列表一样复制我的oracle表的姓氏。所以我会在每个csv行检查这些字段是否在我的列表中,而不是必须执行一个sql请求,我会做一个select count。所以我有2个问题: 这是在.net集合中复制我的表的解决方案似乎很好吗? 如果是的话,你能解释一下如何在.net集合中复制oracle表的内容吗?将.net集合中的表的特定列复制为列表

在此先感谢

回答

0

我认为最有效的方式做到这将是创建一个通用模型类存储每个用户。像这样...

public class User 
{ 
    public string Name { get; set; } 
    public string Surname { get; set; } 
    public int Age { get; set; } 
    public string Country { get; set; } 

    // This comparer will be used to find records that exist or don't exist. 
    public class KeyFieldComparer : IEqualityComparer<User> 
    { 
     public bool Equals(User u1, User u2) 
     { 
      return u1.Name == u2.Name && u1.Surname == u2.Surname; 
     } 

     public int GetHashCode(User u) 
     { 
      return u.Name.GetHashCode()^u.Surname.GetHashCode(); 
     } 
    } 
} 

现在加载两个CSV文件和Oracle表为List<User>对象......

List<User> csvList; 
List<User> oracleList; 

当两个列表中含有数据,这将是很容易看到已经什么存在于每个而不是命中数据库...

// This will filter users that are in the CSV file that don't already exist in oracle. 
var newUsers = csvList.Except(oracleList, new User.KeyFieldComparer()); 

然后,您可以遍历每个新用户并插入...

foreach (var newUser in newUsers) 
    InsertNewUser(newUser); 

希望这是有帮助的。


UPDATE:
我最喜欢的方式是使用微ORM从数据库加载到数据的列表,如Insight.Database。只需在nuget中搜索Insight.Database并安装Insight.Database.Providers.Oracle。然后,您可以查询该表到这样的记忆......

List<User> oracleList; 
using (var db = new OracleConnection(ConnectionString)) 
{ 
    oracleList = db.QuerySql<User>("SELECT Name, Surname, Age, Country FROM Users"); 
} 

只要在你的类模型的属性相匹配,你选择的列的名称,它将正确映射它们(它不区分大小写)。

+0

好的谢谢,我对一个仍然不清楚的部分提出了一些问题。我如何继续在我的数据库中填充用户表的列名和姓氏的oraclelist,在性能方面效率最高,成本最低。 – user2443476 2014-10-31 16:01:13

+0

当我尝试使用Query方法时,我收到了这个错误:'Oracle.DataAccess.Client.OracleConnection'不包含'Query'的定义,也没有包含接受'Oracle.DataAccess'类型的第一个参数的扩展方法'Query' .Client.OracleConnection“可以找到(你是否缺少使用指令或程序集引用?) – user2443476 2014-11-03 09:16:45

+0

右键单击解决方案资源管理器中的项目。点击管理nuget包。确保在线 - > nuget.org在左侧选择。在搜索中输入“insight.database”。在搜索结果中选择Insight.Database.Providers.Oracle,然后单击安装。这应该添加必要的扩展方法。参考:https://github.com/jonwagner/Insight.Database/wiki/A-Quick-Tour – Theo 2014-11-03 15:25:32

0

事实上,您最好的选择是将所有这些留给Oracle。所以..

首先

  1. 用的(姓名,年龄)的结构,你的数据库创建一个临时表。

然后

  1. 装入CSV临时表。
  2. 从您的临时表中选择数据加入针对您的目标表。
  3. 将其余部分(将CSV数据行不存在于目标数据库表中)加载到目标数据库表中。

在那里,一切都完成了。说实话,在.NET方面你不可能比Oracle更快地做到这一点。

步骤2 + 3将是:

insert into target_table (name, surname, age) 
select X.name, X.surname, X.age 
from temporary_table X 
where not exists (
     select 1 
     from target_table Y 
     where Y.name = X.name 
      and Y.surname = X.surname 
    ); 

至于步骤1:使用阵列在C#中分批将数据发送到Oracle或忘掉C#和使用Oracle SQL结合*加载程序或外部表以最快的方式。