I think I am on the right path, but my C# code is not creating document in Azure CosmosDB.
Below is my documentdb code:
using (var client = new DocumentClient(new Uri(endpoint), authkey))
{
Database database = client.CreateDatabaseQuery("SELECT * FROM c WHERE c.id = 'db'").AsEnumerable().First();
var query = new SqlQuerySpec
{
QueryText = "SELECT * FROM c WHERE c.id = #id",
Parameters = new Microsoft.Azure.Documents.SqlParameterCollection { new Microsoft.Azure.Documents.SqlParameter { Name = "#id", Value = collectionId }
}
};
DocumentCollection collection = client.CreateDocumentCollectionQuery(database.SelfLink,query).AsEnumerable().First();
dynamic document1Definition = new
{
name = "Admin",
address = 1,
};
var result = client.CreateDocumentAsync(collection.SelfLink, document1Definition);
}
Also want to point out, currently there are no columns named as "name" and "address" in my collection. So according to my knowledge they are suppose to be created dynamically. Please let me know what wrong are you doing?
See last statement, you are using c# Async method without await.
Use await client.CreateDocumentAsync(collection.SelfLink, document1Definition); or your code will exit before document creation is finished.
Note that your method should change to public async Task methodname(), you will see related tip shown by VS.
Some references for you
Async and Await
How and when to use async and-await
Related
I do multiple mapping on the dapper. Then I try to implement dapper builder
But the it return exception:
Must declare the scalar variable \"#ExecutionId\".\r\nInvalid usage of the option NEXT in the FETCH statement.
Without multiple mapping, never give a problem
Here my snippet code
var Builder = new SqlBuilder();
var SelectedQuery = Builder.AddTemplate(# "SELECT e.[Id], e.[BuyOrderBookId], e.[SellOrderBookId], e.[Volume], e.[Price], e.[CreationDate], e.[StatusId], bo.[UserId], bo.[MarketId], so.[UserId] FROM[dbo].[Execution] AS e JOIN[dbo].[OrderBook] AS bo ON e.BuyOrderBookId = bo.Id JOIN[dbo].[OrderBook] as so ON e.SellOrderBookId = so.Id
/**where**/
ORDER BY e.[CreationDate] DESC OFFSET #skip ROWS FETCH NEXT #take ROWS ONLY;
");
//Execution ID
if (filter.ExecutionId.HasValue)
Builder.Where("e.[Id] = #ExecutionId", new {ExecutionId = filter.ExecutionId.Value
});
var query = await connection.QueryAsync < ExecutionViewModel, OrderBookViewModel, OrderBookViewModel, ExecutionViewModel > (SelectedQuery.RawSql, (execute, buyOrder, sellOrder) => {
execute.BuyUserId = buyOrder.UserId;
execute.SellUserId = sellOrder.UserId;
execute.MarketId = buyOrder.MarketId;
return execute;
},
splitOn: "UserId,UserId",
param: new {
SelectedQuery.Parameters,
skip = (pagingParam.PageNumber - 1) * pagingParam.PageSize,
take = pagingParam.PageSize
});
Anyone know did I do something wrong here?
Update
I just fix like this
if (filter.ExecutionId.HasValue)
Builder.Where(String.Format("e.[Id] = {0}",filter.ExecutionId));
I believe this is not good way to implement. Is risk sql injection.
Try changing the where clause like this:
if (filter.ExecutionId.HasValue)
Builder.Where("e.[Id]", new {Id = filter.ExecutionId.Value});
You can add parameters like this.
if (filter.ExecutionId.HasValue)
{
Builder.Where("e.[Id] = #ExecutionId");
((DynamicParameters)SelectedQuery.Parameters)
.AddDynamicParams(new {
ExecutionId = filter.ExecutionId.Value
});
}
Consider the following database structure (created using EF Code First)
Using simple code as illustrated below I can easily add either new Customers or Suppliers;
private static void InsertCustomers()
{
var customer1 = new Customer
{
FirstName = "Mickey",
LastName = "Mouse",
DateStarted = DateTime.Now
};
var customer2 = new Customer
{
FirstName = "Fred",
LastName = "Flintstone",
DateStarted = DateTime.Now
};
using (var context = new ContactsContext())
{
context.Database.Log = Console.Write; //purely for logging
context.Customers.Add(customer1);
context.Customers.Add(customer2);
context.SaveChanges();
}
}
My question is simple. Fred Flintstone could at some point in the future become a supplier as well as remaining a Customer. From within SSMS I can easily achieve this but I would obviously like to do this from within the application itself. If I use the syntax
var sup = new Supplier();
then the underlying logic will create a new Id (which is perfectly sensible, but undesired as I want to use the existing Id assigned to Fred Flinstone as a Customer which is 2) so how do I in effect add an existing Contacts.Id into the Suppliers table so that it becomes a Primary / foreign key using code in my application.
Well it would transpire that this is not as intuitive in Code First as one might have thought so I have reverted to using the following which does work as intended;
static void CreateSupplier(int id)
{
var contactId = id; //the id being passed in would have been collected from a list of Customers, as we want Fred Flintstone it would have been set to 2
var date = DateTime.UtcNow;
using (var context = new ContactsContext())
{
context.Database.Log = Console.Write; //purely for logging
context.Database.ExecuteSqlCommand(
"INSERT INTO Contacts.Suppliers(Id, DateStarted) VALUES({0}, {1})", contactId, date);
context.SaveChanges();
}
}
It's possible that there is a way to do this with a lambda but at present I haven't found one.
I try to get all data from collection into MongoDB server using C# driver.
The idea is connect to the server and get all collection than insert into list of class.
List<WatchTblCls> wts;
List<UserCls> users;
List<SymboleCls> syms;
public WatchTbl()
{
InitializeComponent();
wts = new List<WatchTblCls>();
users = new List<UserCls>();
syms = new List<SymboleCls>();
}
public async void getAllData()
{
client = new MongoClient("mongodb://servername:27017");
database = client.GetDatabase("WatchTblDB");
collectionWatchtbl = database.GetCollection<WatchTbl>("Watchtbl");
collectionUser = database.GetCollection<UserCls>("Users");
collectionSymbole = database.GetCollection<SymboleCls>("Users");
var filter = new BsonDocument();
using (var cursor = await collectionWatchtbl.FindAsync(filter))
{
while (await cursor.MoveNextAsync())
{
var batch = cursor.Current;
foreach (var document in batch)
{
wts.Add(new WatchTblCls(document["_id"], document["userId"], document["wid"], document["name"], document["Symboles"]));
}
}
}
}
I get this error under
wts.Add(new WatchTblCls(document["_id"], document["userId"], document["wid"], document["name"], document["Symboles"]));
Cannot apply indexing with [] to an expression of type 'WatchTbl'
I don't understand the reason behind using WatchTbl and WatchTblCls both together. Is WatchTblCls a model for the entity WatchTbl here? Im not sure.
In any case. If you go for aggregation and want to convert WatchTbl collection to WatchTblCls list, your desired solution might look like the following. I don't know the defiitions of the classes so I'm assuming:
var client = new MongoClient("mongodb://servername:27017");
var database = client.GetDatabase("WatchTblDB");
var collectionWatchtbl = database.GetCollection<WatchTbl>("Watchtbl");
var collectionUser = database.GetCollection<UserCls>("Users");
var collectionSymbole = database.GetCollection<SymboleCls>("Users");
var list = collectionWatchtbl.AsQueryable().Select(x => new WatchTblCls() {
id = x.id,
userId = x.userId,
.....
});
If you can use the same WatchTbl class and still want to load the full collection to a local List (which is definitely not a good idea):
List<WatchTbl> list = await collectionWatchtbl.Find(x => true).ToListAsync();
for my project, I have to create multiple Quotes and add products to it.
For performance reasons (about 5000 quotes) I am using "ExecuteMultipleRequest()".
This is about what I've got:
var quote = new Quote
{
QuoteNumber = "123",
Name = "test123",
PriceLevelId = new EntityReference(PriceLevel.EntityLogicalName, Pricelevel.Id),
CustomerId = new EntityReference(Account.EntityLogicalName, Customer.Id),
};
_requests.Requests.Add(new CreateRequest { Target = quote });
var quoteDetail = new QuoteDetail
{
QuoteId = new EntityReference(Quote.EntityLogicalName, quote.Id),
ProductId = new EntityReference(Product.EntityLogicalName, product.Id),
IsPriceOverridden = true,
PricePerUnit = new Money(20),
Quantity = Convert.ToDecimal(5),
};
_requests.Requests.Add(new CreateRequest { Target = quoteDetail });
My problem is the quote.Id. I know it is empty until the server processes the request and creates the quote.
Is there a way to tell the server it should use the quotes new id for the quotedetail?
Or is my only way to create the quote itself and then create all details?
What can I do to increase performance if I have to do it this way?
Instead of sending CreateRequests explicity, you could change your code to use the OrganizationServiceContext, which locally tracks changes to objects before submitting them to CRM.
When using the OrganizationServiceContext, you can use AddRelatedObject to both add an object and link it to another one:
Adds a related entity to the OrganizationServiceContext and creates
the link that defines the relationship between the two entities in a
single request.
Alternatively you could manually call AddObject and AddLink.
You final code would look similar to the following:
using (var context = new OrganizationServiceContext(_serviceProxy))
{
var quote = new Quote
{
QuoteNumber = "123",
Name = "test123",
PriceLevelId = new EntityReference(PriceLevel.EntityLogicalName, pricelevel.Id),
CustomerId = new EntityReference(Account.EntityLogicalName, customer.Id),
};
context.AddObject(quote);
var quoteDetail = new QuoteDetail
{
ProductId = new EntityReference(Product.EntityLogicalName, product.Id),
IsPriceOverridden = true,
PricePerUnit = new Money(20),
Quantity = Convert.ToDecimal(5),
};
context.AddRelatedObject(quote, new Relationship("quote_details"), quoteDetail);
context.SaveChanges();
}
Can anyone tell where I make a mistake ? :( I want to insert a row using this. It's just not working. I also tried to use "context.SaveChanges();" but nothing changed. No insert at all, and no exception.
public List<string> Add_Address(string address, int selected_item)
{
List<string> list = new List<string>();
using(var context = new RSS_Reader_Database())
{
Address Address = new Address();
Category_Address Category_Address = new Category_Address();
Address.URL = address.ToString();
int max_id = Convert.ToInt32(context.Addresses.OrderByDescending(t => t.ID_Address).FirstOrDefault());
Category_Address.ID_Address = max_id;
Category_Address.ID_Category = selected_item+1;
var select_query = from t in context.Addresses select t.URL;
foreach (var element in select_query)
{
list.Add(element);
}
}
return list;
}
Edit: Following all Your advices, I made something that works. Looking at this code above, I have no idea what I was trying to do yesterday. Thanks a lot.
public List<string> Add_Address(string address, int selected_item)
{
List<string> list = new List<string>();
using(var context = new RSS_Reader_Database())
{
Address Address = new Address() { URL = address };
context.Addresses.Add(Address);
context.SaveChanges();
int max_id = context.Addresses.Max(u => u.ID_Address);
Category_Address Category_Address = new Category_Address() { ID_Address = max_id, ID_Category = selected_item + 1 };
context.Categories_Addresses.Add(Category_Address);
context.SaveChanges();
var query = from t in context.Addresses
select t.URL;
var data = query.ToList();
foreach (var element in data)
{
list.Add(element);
}
}
return list;
}
Saving with Entity Framework generally works like this. Using your above code as a starting point.
using(var context = new RSS_Reader_Database())
{
Address address = new Address();
// Set address properties
context.Addresses.Add(address);
context.SaveChanges();
}
You need to add the object to the DbSet<T> where T is the type of the entity that is defined on the DbContext. You then need to call SaveChanges() on the context.
I would suggest reading this. It is an easy to follow introduction to Entity Framework.
Not sure exactly what you are trying to do.
But if you are expecting to insert the data by the list.Add(element); command it won't work.
If you are planning to insert data into the same DB, you need to use one property from the context to represent the List collection add a new element on this property.
Something like:
context.Lists.Add(element);
if you want retrieve data, you should not call SaveChanges() !,
try get all values from one query like this:
List<string> select_query = (from t in context.Addresses select t.URL).ToList();