I dont have overload for EF savechanges, and no acceptallchanges available - c#-4.0

I am very confused, i am trying in vain to queue up multiple inserts i have thousands of adds to do so i only want to really do the database once.
I am using .net 4 and entity framework 4 and also added reference to system.data.objects
but i still have no overload available for SaveChanges
here is my code:
using (TransactionScope scope = new TransactionScope())
{
using (myDbContext context = new myDbContext)
{
foreach (var p in model)
{
var tempProduct = new Products();
// set a loopable list of available products
IEnumerable<MerchantProductFeedMerchantProd> prod = p.prod;
foreach (var i in prod)
{
var prodText = i.text.FirstOrDefault();
var prodUri = i.uri.FirstOrDefault();
var prodPrice = i.price.FirstOrDefault();
FillTempProduct(feedId, i, tempProduct, supplierId, feedInfo, prodPrice, prodText,
prodUri);
context.Products.Add(tempProduct);
context.SaveChanges(false); // no overload
}
scope.Complete();
context.AcceptAllChanges(); //acceptallchanges not referenced ??
}
}
this is really battering my head now, so any help would be much appreciated.
thanks

Because you are using DbContext API and these methods are from ObjectContext API. DbContext API is simplified = it is only for simple requirements. If you have more complex requirements you must use ObjectContext API by converting your DbContext to ObjectContext instance:
var objectContext = ((IObjectContextAdapter)myDbContext).ObjectContext;

Related

How to call Azure Actions in xamarin forms using Azure Service Provider

I am using Azure Service provider (Azure SDK in xamarin forms) to download data from Azure cloud Server, I am using bellow code to fetch all data
var table = AzureServiceProvider.Instance.GetRemoteTable<T>();
var query = table.CreateQuery();
if (filter != null)
{
query = table.Where(filter);
}
List<T> azureDatas;
await query.ToListAsync();
when I use code above it hits following URL https://MyService.azurewebsites.net/tables/TableName
But now I have to pass id (i.e api/table/{TableName}/{controller}/{id}) to fetch only required data for matching that that id
using above same code its hitting above URL
https://MyService.azurewebsites.net/tables/TableName
Inst ed of that I want to use
EX:-
https://mobilddevservice.azurewebsites.net/tables/TableName/(methodName)/(ID)10338654
I don't know if you figures this out yet, but to target a specific method in your controller you can use the ".WithParameters" method on your table.
So lets say you have 2 methods in your controller:
// GET tables/TableName/id
public SingleResult<TableName> GetDataFromName(string name)
{
//Your logic here
}
// GET tables/TableName/id
public SingleResult<TableName> GetDataFromAddress(string address)
{
//Your logic here
}
You can access these methods individually by using the .WithParameters like:
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters.Add("name", name);
var query = Table.WithParameters(parameters);
var results = await query.ToEnumerableAsync();
To access the address method
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters.Add("address", personsAddress);
var query = Table.WithParameters(parameters);
var results = await query.ToEnumerableAsync();
So the important part is:
As far as I'm aware you can only send strings. But I might be
wrong
The name in the parameters dictionary has to be the exact
name of the variable in your controller!
Use the following for a lookup by Id:
var table = client.GetTable<T>();
var record = await table.LookupAsync(id);
It uses the different endpoint - https://site.azurewebsites.net/tables/Table/{id}.
For more info, check the book: https://adrianhall.github.io/develop-mobile-apps-with-csharp-and-azure/chapter3/client/

Kentico CMSForms in a live context

I created a cms form field would like to get the value of it at runtime from the codebehind of one of my template classes. Is this possible?
Thanks in Advance
Here is your code:
using CMS.DataEngine;
using CMS.Helpers;
using CMS.OnlineForms;
using CMS.SiteProvider;.
...
...
...
var formInfo = BizFormInfoProvider.GetBizFormInfo("ContactUs", SiteInfoProvider.GetSiteInfo("mySiteID").SiteID);
var className = DataClassInfoProvider.GetDataClassInfo(formInfo.FormClassID).ClassName;
var data = BizFormItemProvider.GetItems(className);
if (!DataHelper.DataSourceIsEmpty(data))
{
foreach (var item in data)
{
var myFieldValue = item.GetStringValue("MyFieldColumnName", "");
}
}
You can find more info here.
This article by Kentico will solve your problem and have extensive article on using Bizform API.
https://docs.kentico.com/plugins/servlet/mobile#content/view/58331946

Access resources by Id in Azure DocumentDB

I just started playing with Azure DocumentDB and my excitement has turned into confusion. This thing is weird. It seems like everything (databases, collections, documents) needs to be accessed not by its id, but by its 'SelfLink'. For example:
I create a database:
public void CreateDatabase()
{
using (var client = new DocumentClient(new Uri(endpoint), authKey))
{
Database db = new Database()
{
Id = "TestDB",
};
client.CreateDatabaseAsync(db).Wait();
}
}
Then later sometime I want to create a Collection:
public void CreateCollection()
{
using (var client = new DocumentClient(new Uri(endpoint), authKey))
{
DocumentCollection collection = new DocumentCollection()
{
Id = "TestCollection",
};
client.CreateDocumentCollectionAsync(databaseLink: "???", documentCollection: collection).Wait();
}
}
The api wants a 'databaseLink' when what I'd really prefer to give it is my database Id. I don't have the 'databaseLink' handy. Does DocumentDB really expect me to pull down a list of all databases and go searching through it for the databaseLink everytime I want to do anything?
This problem goes all the way down. I can't save a document to a collection without having the collection's 'link'.
public void CreateDocument()
{
using (var client = new DocumentClient(new Uri(endpoint), authKey))
{
client.CreateDocumentAsync(documentCollectionLink: "???", document: new { Name = "TestName" }).Wait();
}
}
So to save a document I need the collection's link. To get the collections link I need the database link. To get the database link I have to pull down a list of all databases in my account and go sifting through it. Then I have to use that database link that I found to pull down a list of collections in that database that I then have to sift through looking for the link of the collection I want. This doesn't seem right.
Am I missing something? Am I not understanding how to use this? Why am I assigning ids to all my resources when DocumentDB insists on using its own link scheme to identify everything? My question is 'how do I access DocumentDB resources by their Id?'
The information posted in other answers from 2014 is now somewhat out of date. Direct addressing by Id is possible:
Although _selflinks still exist, and can be used to access resources, Microsoft have since added a much simpler way to locate resources by their Ids that does not require you to retain the _selflink :
UriFactory
UriFactory.CreateDocumentCollectionUri(databaseId, collectionId))
UriFactory.CreateDocumentUri(databaseId, collectionId, "document id");
This enables you to create a safe Uri (allowing for example for whitespace) - which is functionally identical to the resources _selflink; the example given in the Microsoft announcement is shown below:
// Use **UriFactory** to build the DocumentLink
Uri docUri = UriFactory.CreateDocumentUri("SalesDb", "Catalog", "prd123");
// Use this constructed Uri to delete the document
await client.DeleteDocumentAsync(docUri);
The announcement, from August 13th 2015, can be found here:
https://azure.microsoft.com/en-us/blog/azure-documentdb-bids-fond-farewell-to-self-links/
I would recommend you look at the code samples here in particular the DocumentDB.Samples.ServerSideScripts project.
In the Program.cs you will find the GetOrCreateDatabaseAsync method:
/// <summary>
/// Get or create a Database by id
/// </summary>
/// <param name="id">The id of the Database to search for, or create.</param>
/// <returns>The matched, or created, Database object</returns>
private static async Task<Database> GetOrCreateDatabaseAsync(string id)
{
Database database = client.CreateDatabaseQuery()
.Where(db => db.Id == id).ToArray().FirstOrDefault();
if (database == null)
{
database = await client.CreateDatabaseAsync(
new Database { Id = id });
}
return database;
}
To answer you question, you can use this method to find your database by its id and other resources (collections, documents etc.) using their respective Create[ResourceType]Query() methods.
Hope that helps.
The create database call returns a the database object:
var database = client.CreateDatabaseAsync(new Database { Id = databaseName }).Result.Resource;
And then you can use that to create your collection
var spec = new DocumentCollection { Id = collectionName };
spec.IndexingPolicy.IndexingMode = IndexingMode.Consistent;
spec.IndexingPolicy.Automatic = true;
spec.IndexingPolicy.IncludedPaths.Add(new IndexingPath { IndexType = IndexType.Range, NumericPrecision = 6, Path = "/" });
var options = new RequestOptions
{
ConsistencyLevel = ConsistencyLevel.Session
};
var collection = client.CreateDocumentCollectionAsync(database.SelfLink, spec, options).Result.Resource;
The client.Create... methods return the objects which have the self links you are looking for
Database database = await client.CreateDatabaseAsync(
new Database { Id = "Foo"});
DocumentCollection collection = await client.CreateDocumentCollectionAsync(
database.SelfLink, new DocumentCollection { Id = "Bar" });
Document document = await client.CreateDocumentAsync(
collection.SelfLink, new { property1 = "Hello World" });
For deleting the document in partitioned collection, please leverage this format:
result = await client.DeleteDocumentAsync(selfLink, new RequestOptions {
PartitionKey = new PartitionKey(partitionKey)
});

Entity Framework 5 deep copy/clone of an entity

I am using Entity Framework 5 (DBContext) and I am trying to find the best way to deep copy an entity (i.e. copy the entity and all related objects) and then save the new entities in the database. How can I do this? I have looked into using extension methods such as CloneHelper but I am not sure if it applies to DBContext.
One cheap easy way of cloning an entity is to do something like this:
var originalEntity = Context.MySet.AsNoTracking()
.FirstOrDefault(e => e.Id == 1);
Context.MySet.Add(originalEntity);
Context.SaveChanges();
the trick here is AsNoTracking() - when you load an entity like this, your context do not know about it and when you call SaveChanges, it will treat it like a new entity.
If MySet has a reference to MyProperty and you want a copy of it too, just use an Include:
var originalEntity = Context.MySet.Include("MyProperty")
.AsNoTracking()
.FirstOrDefault(e => e.Id == 1);
Here's another option.
I prefer it in some cases because it does not require you to run a query specifically to get data to be cloned. You can use this method to create clones of entities you've already obtained from the database.
//Get entity to be cloned
var source = Context.ExampleRows.FirstOrDefault();
//Create and add clone object to context before setting its values
var clone = new ExampleRow();
Context.ExampleRows.Add(clone);
//Copy values from source to clone
var sourceValues = Context.Entry(source).CurrentValues;
Context.Entry(clone).CurrentValues.SetValues(sourceValues);
//Change values of the copied entity
clone.ExampleProperty = "New Value";
//Insert clone with changes into database
Context.SaveChanges();
This method copies the current values from the source to a new row that has been added.
This is a generic extension method which allows generic cloning.
You have to fetch System.Linq.Dynamic from nuget.
public TEntity Clone<TEntity>(this DbContext context, TEntity entity) where TEntity : class
{
var keyName = GetKeyName<TEntity>();
var keyValue = context.Entry(entity).Property(keyName).CurrentValue;
var keyType = typeof(TEntity).GetProperty(keyName, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance).PropertyType;
var dbSet = context.Set<TEntity>();
var newEntity = dbSet
.Where(keyName + " = #0", keyValue)
.AsNoTracking()
.Single();
context.Entry(newEntity).Property(keyName).CurrentValue = keyType.GetDefault();
context.Add(newEntity);
return newEntity;
}
The only thing you have to implement yourself is the GetKeyName method. This could be anything from return typeof(TEntity).Name + "Id" to return the first guid property or return the first property marked with DatabaseGenerated(DatabaseGeneratedOption.Identity)].
In my case I already marked my classes with [DataServiceKeyAttribute("EntityId")]
private string GetKeyName<TEntity>() where TEntity : class
{
return ((DataServiceKeyAttribute)typeof(TEntity)
.GetCustomAttributes(typeof(DataServiceKeyAttribute), true).First())
.KeyNames.Single();
}
I had the same issue in Entity Framework Core where deep clone involves multiple steps when children entities are lazy loaded. One way to clone the whole structure is the following:
var clonedItem = Context.Parent.AsNoTracking()
.Include(u => u.Child1)
.Include(u => u.Child2)
// deep includes might go here (see ThenInclude)
.FirstOrDefault(u => u.ParentId == parentId);
// remove old id from parent
clonedItem.ParentId = 0;
// remove old ids from children
clonedItem.Parent1.ForEach(x =>
{
x.Child1Id = 0;
x.ParentId= 0;
});
clonedItem.Parent2.ForEach(x =>
{
x.Child2Id = 0;
x.ParentId= 0;
});
// customize entities before inserting it
// mark everything for insert
Context.Parent.Add(clonedItem);
// save everything in one single transaction
Context.SaveChanges();
Of course, there are ways to make generic functions to eager load everything and/or reset values for all keys, but this should make all the steps much clear and customizable (e.g. all for some children to not be cloned at all, by skipping their Include).

Using FindView in Orchard

I'm trying to use:
var viewEngineResult = ViewEngines.Engines.FindView(ControllerContext, myViewName, null);
as part of a process to render the contents of a view to send nice formatted emails. I'm using it inside an Orchard Controller. I have used similar code outside of Orchard in an MVC project and it works fine.
However in Orchard running this code fails to find the view I'm looking for and returns a view engine result that has searched 0 locations.
viewEngineResult has the following values after it is called:
SearchedLocations: Count = 0,
View: null,
ViewEngine: null
Is there a reason this doesn't work in Orchard and is there a way to make it work?
This answer is based on the advise given me by Bertrand, but I wanted to bring it together with what I'd discovered.
To be able to use FindPartialView I needed to inject an instance of IViewEngineProvider into my controller.
I then used the following code to resolve and render a view:
private String RenderView(String viewName, object model)
{
var paths = new List<string>(); // This can just be an empty list and it still finds it.
var viewEngine = _viewEngineProvider.CreateModulesViewEngine(new CreateModulesViewEngineParams {VirtualPaths = paths});
var viewResult = viewEngine.FindPartialView(ControllerContext, viewName, false);
if (viewResult.View == null) {
throw new Exception("Couldn't find view " + viewName);
}
var viewData = new ViewDataDictionary {Model = model};
using (var sw = new StringWriter())
{
var viewContext = new ViewContext(ControllerContext, viewResult.View, viewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
return sw.GetStringBuilder().ToString();
}
}
I think you'll want to take a close look at Orchard.Framework/Mvc/ViewEngines, in particular IViewEngineProvider and ThemeAwareViewEngine. There's a lot more going on when in Orchard, such as themes, multi-tenancy, and a richer environment in general that may be needed to make this work.
What's likely happening here is that the view engines don't have enough information to resolve a view and thus opt out of the chain. You might want to put a breakpoint into ThemeAwareViewEngine.FindView, and then inspect the private dependency fields of that class. I wouldn't be surprised if they were null, because getting to FindView through statics will probably not allow dependency injection to do its stuff properly.
Then again I'm just guessing.

Resources