Reputation: 5862
In there i used this code to read data of excel file and it's work for me properly. But i need to save this dataset to database with WCF
. So think pass the dataset
to wcf method to achieve this.But how can i do this
this is i tried code with windows form application
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog opn = new OpenFileDialog();
opn.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm";
if (opn.ShowDialog() == DialogResult.Cancel)
return;
FileStream strm = new FileStream(opn.FileName, FileMode.Open);
IExcelDataReader excldr = ExcelReaderFactory.CreateOpenXmlReader(strm);
DataSet rslt = excldr.AsDataSet();
// while (excldr.Read())
// {
// Console.WriteLine(excldr.GetString(1));
// }
}
I need to pass DataSet rslt
to WCF
method and within WCF
i think to write save data function.is this good practice or not ? So how i can i do this
Upvotes: 0
Views: 2546
Reputation: 3885
After reading your comment I thought I should give you some example how to tackle this problem in a slightly better way.
My approach would be to initialise Request/Response DataContract
objects that allows client to send the dataset and receive the acknowledgement more effectively.
Here is the DataContract
classes:
The request object that client will instantiate and populate and send to the service:
[DataContract]
public class SaveDataSetRequest
{
[DataMember]
public DataSet Data { get; set; }
[DataMember]
public string FileName { get; set; }
// you can add more properties here in the future versions without effecting the existing clients.
}
The response object that service will instantiate and populate and send back to the client:
[DataContract]
public class SaveDataSetResponse
{
public string Message { get; set; }
}
The service contract:
[ServiceContract]
public interface IDataService
{
[OperationContract]
SaveDataSetResponse SaveDataSet(SaveDataSetRequest request);
}
and its implementation:
public class DataService : IDataService
{
public SaveDataSetResponse SaveDataSet(SaveDataSetRequest request)
{
SaveDataSetResponse response = new SaveDataSetResponse();
try
{
// save or processes your data set from request.Data object,
// once this operation is completed successfully then return the success message.
response.Message = "Success";
}
catch (Exception ex)
{
// log your exception
response.Message = $"Unable to save / process the data. Reason: {ex.Message}";
}
return response;
}
}
You will need to update the service config something like this (if you havent)
<endpoint
address="http://localhost:8000/<namespace>/IDataService"
binding="netTcpBinding"
contract="<namespace>.IDataService"
name="DataService">
</endpoint>
On the client, update the service reference (adding a new version of service dll or service url - WSDL), create an instance of client proxy class and call SaveDataSetResponse SaveDataSet(SaveDataSetRequest request)
method. Make sure that the client config - endpoint is also updated with new contract if you are copying this code as is.
Some useful links:
Upvotes: 1
Reputation: 5862
I solved my problem :)
private void button2_Click(object sender, EventArgs e)
{
ServiceReference1.Service2Client obj = new ServiceReference1.Service2Client();
OpenFileDialog opn = new OpenFileDialog();
opn.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm";
if (opn.ShowDialog() == DialogResult.Cancel)
return;
try
{
FileStream strm = new FileStream(opn.FileName, FileMode.Open);
IExcelDataReader excldr = ExcelReaderFactory.CreateOpenXmlReader(strm);
DataSet rslt = excldr.AsDataSet();
obj.insertExecl(rslt);
}
catch (IOException x)
{
MessageBox.Show(x.Message);
}
}
Service2.cs
public class Service2 : IService2
{
public void insertExecl(DataSet rslt)
{
DataClasses1DataContext conn = new DataClasses1DataContext();
foreach (DataTable table in rslt.Tables)
{
foreach (DataRow dr in table.Rows)
{
tblExcel addTbl = new tblExcel()
{
SID = Convert.ToString(dr[0]),
Name = Convert.ToString(dr[1]),
Address = Convert.ToString(dr[2])
};
conn.tblExcels.InsertOnSubmit(addTbl);
}
}
conn.SubmitChanges();
//excldr.Close();
//strm.Close();
Console.WriteLine("successfully");
}
}
IService2.cs
[ServiceContract]
public interface IService2
{
[OperationContract]
void insertExecl(DataSet rslt);
}
Upvotes: 0
Reputation: 321
Passing a DataTable or a DataSet through WCF is a highly debated topic. It can be done easily, however Personally i prefer to pass the data itself and not the metadata (columns and rows definitions, data relations etc.) I usually declare an object , expose it to WCF and transfer it.
For each of the tables in your DataSet You can do something like the following (not tested) :
public class ExcelService : IExcelService
{
public List<CustomExcelData> GetExcelData()
{
List<CustomExcelData> excelDataList = new List<CustomExcelData>();
OpenFileDialog opn = new OpenFileDialog();
opn.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm";
if (opn.ShowDialog() == DialogResult.Cancel)
return null;
FileStream strm = new FileStream(opn.FileName, FileMode.Open);
IExcelDataReader excldr = ExcelReaderFactory.CreateOpenXmlReader(strm);
DataSet rslt = excldr.AsDataSet();
DataTable dt = rslt.Tables[0];
if (dt != null && dt.Rows.Count > 0)
{
foreach (DataRow row in dt.Rows)
{
excelDataList.Add(new CustomExcelData(row));
}
}
return excelDataList;
}
}
and the interface :
[ServiceContract]
interface IExcelService
{
[OperationContract]
List<CustomExcelData> GetExcelData();
}
[DataContract]
public class CustomExcelData
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string Address { get; set; }
[DataMember]
public DateTime BirthDate { get; set; }
public CustomExcelData(DataRow row)
{
Name = row["NameField"].ToString();
Address = row["AddressField"].ToString();
BirthDate = DateTime.Parse(row["BirthDateField"].ToString());
}
}
Upvotes: 1