TheBigBearNow Ответов: 2

В C# сохранить 2 объекта DataTable потом базу потом выкл/вкл спасает повторяющиеся данные


Я сохраняю входящие данные в DataTable. Я хотел бы сохранить этот DataTable в таблице базы данных, чтобы у меня были записаны все данные. Как часто, по-вашему, я должен записывать эти данные в базу данных?
Также я должен сохранить данные построчно с SQL-запрос, или использовать хранимую процедуру, или я должен сохранить данные с помощью SqlBulkCopy

private void BtnStartCapture_Click(object sender, RoutedEventArgs e)
        {
            if (!Running)
            {
                Running = true;
                var incomingData = BinanceSocketClient.SubscribeToTradeUpdatesAsync("BTCUSD", (data) =>
                {
                    _ = AddNewIncomingTradeAsync(data);
                    AddDataRow(data);
                    counter++;
                    if(counter >= 2 )
                    {
                        SaveToDBTableV2();
                        counter = 0;
                    }
                });
                IncomingStreamOn();
            }            
        }
public void AddDataRow(BinanceStreamTrade data)
        {
            if(DataTable != null)
            {
                DataRow row = DataTable.NewRow();
                row["TradeID"] = data.OrderId;
                row["Price"] = data.Price;
                row["Quantity"] = data.Quantity;
                row["TradeTime"] = data.TradeTime;
                row["Symbol"] = data.Symbol;
                row["BuyerID"] = data.BuyerOrderId;
                row["SellerID"] = data.SellerOrderId;
                DataTable.Rows.Add(row);
            }
        }
public void SaveToDBTableV2()
        {
            using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.Connection))
            {
                connection.Open();
                using (SqlBulkCopy bulkCopy = new SqlBulkCopy(connection))
                {
                    bulkCopy.DestinationTableName = "dbo.EmailTest";

                    try
                    {
                        SqlBulkCopyColumnMapping TradeID = new SqlBulkCopyColumnMapping("TradeID", "TradeID");
                        bulkCopy.ColumnMappings.Add(TradeID);
                        SqlBulkCopyColumnMapping Price = new SqlBulkCopyColumnMapping("Price", "Price");
                        bulkCopy.ColumnMappings.Add(Price);
                        SqlBulkCopyColumnMapping Quantity = new SqlBulkCopyColumnMapping("Quantity", "Quantity");
                        bulkCopy.ColumnMappings.Add(Quantity);
                        SqlBulkCopyColumnMapping TradeTime = new SqlBulkCopyColumnMapping("TradeTime", "TradeTime");
                        bulkCopy.ColumnMappings.Add(TradeTime);
                        SqlBulkCopyColumnMapping Symbol = new SqlBulkCopyColumnMapping("Symbol", "Symbol");
                        bulkCopy.ColumnMappings.Add(Symbol);
                        SqlBulkCopyColumnMapping BuyerID = new SqlBulkCopyColumnMapping("BuyerID", "BuyerID");
                        bulkCopy.ColumnMappings.Add(BuyerID);
                        SqlBulkCopyColumnMapping SellerID = new SqlBulkCopyColumnMapping("SellerID", "SellerID");
                        bulkCopy.ColumnMappings.Add(SellerID);
                        bulkCopy.WriteToServer(DataTable, DataRowState.Added);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message);
                    }
                }
            }
        }


Что я уже пробовал:

В настоящее время я использую SqlBulkCopy, в чем разница от сохранения его с помощью простого запроса вставки по сравнению с этим?
Я также не хочу иметь дубликаты данных, в настоящее время я сохраняю datatable в базе данных, и я продолжаю сохранять его, и он работает отлично, но когда я останавливаю websocket и снова включаю его, а затем иду, чтобы сохранить данные, он повторно сохраняет все данные в datatable, так что я получаю дубликаты данных. Что бы вы посоветовали мне сделать для этой задачи? Что бы вы сделали, чтобы не получить дублирующиеся данные?

Gerry Schmitz

Вам нужны "цифры". Все остальное похоже на покупку брюк (онлайн), не зная размера своей талии.

2 Ответов

Рейтинг:
6

TheBigBearNow

Вот ответ, который я получил.

public async Task SaveToDBTableV5()
        {
            using (SqlConnection connection = new SqlConnection(Properties.Settings.Default.Connection))
            {
                connection.Open();
                SqlCommand cmd = new SqlCommand("dbo.INSERTEmailTestV2", connection);
                cmd.CommandType = CommandType.StoredProcedure;
                try
                {
                    cmd.Parameters.AddWithValue("@EmailTstType", DataTable);
                    cmd.ExecuteNonQuery();
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
CREATE TYPE [dbo].[EmailTstType] AS TABLE(
	[ID] [int] NULL,
	[TradeID] [int] NULL,
	[Price] [decimal](18, 0) NULL,
	[Quantity] [decimal](18, 0) NULL,
	[TradeTime] [datetime] NULL,
	[Symbol] [nvarchar](150) NULL,
	[EventType] [nvarchar](150) NULL,
	[IsMaker] [int] NULL,
	[EventTime] [datetime] NULL,
	[BuyerID] [int] NULL,
	[SellerID] [int] NULL,
	[Filled] [bit] NULL,
	[Name] [nvarchar](100) NULL
 )
CREATE PROCEDURE [dbo].[INSERTEmailTestV2]
	@EmailTstType EmailTstType READONLY
AS
BEGIN
	-- SET NOCOUNT ON added to prevent extra result sets from	-- interfering with SELECT statements.
	SET NOCOUNT ON;

	MERGE INTO dbo.EmailTest e1
	USING @EmailTstType e2
	ON e1.TradeID = e2.TradeID
	WHEN NOT MATCHED THEN
	INSERT VALUES (e2.TradeID, e2.Price, e2.Quantity, e2.TradeTime, e2.Symbol, e2.EventType, 
				   e2.IsMaker, e2.EventTime, e2.BuyerID, e2.SellerID, e2.Filled, e2.Name);
END


Рейтинг:
1

Garth J Lancaster

Как сказал Джерри, все зависит от цифр .. Я отмечаю, что у вас нет "стоп-захвата данных" или вы не показали его здесь, если у вас есть такой .. так что, возможно, подход 1, Возьмите это

private void BtnStartCapture_Click(object sender, RoutedEventArgs e)
        {
            if (!Running)
            {
                Running = true;
                var incomingData = BinanceSocketClient.SubscribeToTradeUpdatesAsync("BTCUSD", (data) =>
                {
                    _ = AddNewIncomingTradeAsync(data);
                    AddDataRow(data);
                    counter++;
                    if(counter >= 2 )
                    {
                        SaveToDBTableV2();
                        counter = 0;
                    }
                });
                IncomingStreamOn();
            }            
        }
и уберите это
SaveToDBTableV2();
(и, возможно, логика счетчика), так что вы создаете еще одну кнопку "остановить захват данных" и событие для нажатия кнопки
private void BtnStopCapture_Click(object sender, RoutedEventArgs e)
{
  SaveToDBTableV2();
}


Кроме того, я не уверен, что это делает
_ = AddNewIncomingTradeAsync(data);
так что, возможно, потребуется "переезд" ....


TheBigBearNow

My websockets are almost 'ALWAYS' running. I do have a stopcapture button but it doesnt get clicked often because I dont want it off. Its a trading bot that runs and captures all incoming data. I need to record all incoming data which are trades. I would like to record all the incoming data but i dont know how often i should save it to a table. and which method to use to save it. Addnewinconingtradeasync shows all the incoming data on a listview. my stopcapture just currently shuts off the websocket. Right now my code almost works. It saves all data to a database but when i click stopcapture then turn it back on it saves the whole datatable again creating duplicate rows. I would like to know is this a good way i have it setup?

Garth J Lancaster

"Я хотел бы знать, это хороший способ, которым я его настроил?" .. ну, я бы сказал Нет - вы все еще хотите отделить сделку, полученную от обработки (поэтому вы не хотите блокировать свой сокет) .. это все еще зависит от количества и скорости (полученных сделок) - я бы посмотрел на добавление полученной сделки в (возможно) общую структуру данных/данных, возможно, запуск события, чтобы сказать, что данные прибыли, но затем обработка этих данных во втором (и безопасном) потоке - здесь также можно было бы использовать наблюдаемую коллекцию ... вам тоже нужна надежность ? что произойдет, если вы "отбросите" сделку ?