Fetching details on an entity in Breeze using Employee('1234') - breeze

I want fetch the details of a Collection in Odata services like the following URL
http://my.company.com/odata/Employee('1234')/Details
I tried with the following code to do so. Not sure whether fromEntityKey is the right thing to do or anything else.
manager = new breeze.EntityManager(collectionData.serviceName);
var empType = manager.metadataStore.getEntityType("Employees");
var entityKey = new EntityKey(empType, '1234');
var query = EntityQuery.fromEntityKey(entityKey);
But it gives me an error "Be sure to execute a query or call fetchMetadata first."
I also tried that from this link. But I'm still getting the same.
Can any one help me on this?

You can't use manager.metadataSote.getEntityType("Employees") until metadata has been retrieved from the server. By default this occurs during the first query operation, but your code is attempting to use the metadata before it has been retrieved.
Also, I think that you are confusing the name of your resource "Employees" with the type of the instances returned by your resource, probably "Employee". I would also check whether your key's datatype is numeric or a string. The example below assume its numeric (unlike your example where the datatype of the key is presumably a string because you are quoting it).
So you have two approaches, either force the metadata to be fetched before you compose your query, like this:
manager = new breeze.EntityManager(serviceName);
manager.fetchMetadata().then(function () {
var empType = manager.metadataStore.getEntityType("Employee");
var entityKey = new EntityKey(empType, 1);
var query = EntityQuery.fromEntityKey(entityKey);
// if you want to also see the queries details
query = query.expand("Details");
return manager.executeQuery(query);
}).then(function (data) {
var results = data.results;
ok(results.length === 1, "should have returned a single record");
var emp = results[0];
));
or if you know the string name of the 'key' ("Id" in the example below) field, use it directly
manager = new breeze.EntityManager(serviceName);
var query = EntityQuery.from("Employees")
.where("Id", "==", 1)
.expand("Details");
manager.executeQuery(query).then(function(data) {
var results = data.results;
var emp = results[0];
});

Related

Convert datasource guid to string value in sitecore rendering

In sitecore, when getting the datasource from the renderingcontext, it returns a guid. Is there a means to convert this to the actual string value stored in the datasource field.
I want to run a "fast" query but need the path stored in the rendering context datasource instead of the guid.
Thanks,
If what you receive is a Guid, you can use
var idString = guid.ToString("B");
if what you receive is Sitecore.Data.ID, just use:
var idString = id.ToString();
The guid that you are getting is the Sitecore ID of the datasource item. You should be able to get it's path directly:
var dataSource = Sitecore.Context.Database.GetItem(RenderingContext.CurrentOrNull.Rendering.DataSource);
var dataSourcePath = dataSource.Paths.Path;

Entity Framework: Select field name causing error

The moment I mention field names when fetching data from db, I start getting errors.
Before my code was this and it was working:
var customer = from s in db.Customers
select s;
The moment I change it to:
var customer = (from s in db.Customers
select new
{
CompanyName = s.CompanyName,
ContactName = s.ContactName,
ContactTitle = s.ContactTitle,
Address = s.Address,
});
I start getting error as follows:
The model item passed into the dictionary is of type
'PagedList.PagedList1[<>f__AnonymousType24[System.String,System.String,System.String,System.String]]',
but this dictionary requires a model item of type
'PagedList.IPagedList`1[MVCCRUDPageList.Models.Customer]'.
My view looks like:
#model PagedList.IPagedList<MVCCRUDPageList.Models.Customer>
#using PagedList.Mvc;
This error is caused because you are not sending the Customer model to the view.
By doing select new { ... } you are creating an anonymous object.
You may consider changing your code to:
select new MVCCRUDPageList.Models.Customer
{
CompanyName = s.CompanyName,
ContactName = s.ContactName,
ContactTitle = s.ContactTitle,
Address = s.Address,
}
You may still need to convert the IQueryable to IPagedList
The error is telling you that the view is expecting one type but you are passing it another type. The Linq Select method you have is projecting to an anonymous type instead of the expected Customer class. Change your code to match, something like this
var customer = (from s in db.Customers
select new Customer //<--- This here, you may need to use
// the full namespace MVCCRUDPageList.Models
{
CompanyName = s.CompanyName,
ContactName = s.ContactName,
ContactTitle = s.ContactTitle,
Address = s.Address,
});

Populate List in Swift 2.0 and display results

I've been learning iOS development for the past three weeks, I'm currently following a course on Udemy so far so good.
However I'm following one of the lectures whereby we build an Instagram Clone.
The instructor is using three arrays which are as follows:
var usernames = [""] // Stores all usernames
var userIds = [""] // Stores all Id's of the given usernames
var isFollowing = [false] // Stores where or not you're following that user
To me trying to keep track of what userId goes with what username using two arrays is basically an accident waiting to happen so I decided to set off and find a more feasible approach. I reverted back to my .Net days and decided to create a list so I went and created a class as follows:
class Users{
var Username : NSString = ""
var UserId : NSString = ""
var Following : Bool = false
}
Now inside my ViewController I make a call to Parse which returns me a list of users and I'm basically trying to loop through the response, and add them to the list class as shown here:
var t = [Users]() // After googling the web, this seems to be the syntax for a list declaration ?
let u = Users()
for object in users{
if let o = object as? PFUser {
u.Username = o.username!
u.UserId = o.objectId!
u.Following = o.IsFollowing!
self.t.append(u)
}
}
print(self.t)
Now when I print this to the console I see the following:
ParseStarterProject_Swift.Users
As I have one user at present, however when I try to loop through T and display the username in the console it doesn't display anything.
for x in t {
print(x.Username)
}
Your basic intuition is correct, it's better to have an array of custom objects, not multiple arrays.
Regarding making it more Swifty, consider your Users type. You might want something like:
struct User {
let username: String
let userId: String
let following: Bool
}
Note,
property names should start with lowercase letter;
Users should probably be called User, as it represents a single user;
we don't generally initialize values to default values like that, but rather specify them in the initializer;
we probably use String not NSString;
if a property cannot change, you'd use let, not var;
properties begin with lower case letters;
Then you can do something like:
var t = [User]()
for object in users {
if let o = object as? PFUser {
t.append(User(username: o.username!, userId: o.objectId!, following: o.IsFollowing!)
}
}
print(t)
Clearly, with all of those ! forced unwrapping operators, you'd want to be confident that those fields were populated for all of those properties.
Using struct is nice because (a) it's a value type; (b) you get the initializer for free; and (c) you can just print them. If you really wanted User to be a reference type (a class), you'd do something like:
class User {
let username: String
let userId: String
let following: Bool
init(username: String, userId: String, following: Bool) {
self.username = username
self.userId = userId
self.following = following
}
}
And if you wanted to be able to just print them, you'd define it to conform to CustomStringConvertible:
extension User: CustomStringConvertible {
var description: String { return "<User; username = \(username); userId = \(userId); following = \(following)>" }
}
With the class, you can feel free to change that description computed property to show it in whatever format you want, but it illustrates the idea.
You are correct in considering that keeping track of what userId goes with what username using two arrays is dangerous, you in the correct direction with your approach.
First, I would just like to suggest that you use correct naming convention:
Classes should be singular (except in very specific cases).
Variable/property names should begin with lowercase.
This would mean that your user class should look like this:
class User {
var username : NSString = ""
var userId : NSString = ""
var following : Bool = false
}
I will keep your existing naming use for the next part. The main problem with your code is that the variable "u" is a object which you create only once and then modify it. You should be creating a new "Users" object for each user instead of modifying the original. If you don't do this you will just have an array with the same user multiple times. This is how your code would look now:
var t = [Users]()
for object in users {
if let o = object as? PFUser {
let u = Users()
u.Username = o.username!
u.UserId = o.objectId!
u.Following = o.IsFollowing!
self.t.append(u)
}
}
print(self.t)
Next you mention that when you print to console you see the text: ParseStarterProject_Swift.Users, that is because Swift does not automatically print a pretty text with the content of your object. In order for it to print something more detailed, your "Users" object would need to implement the CustomStringConvertible. You can see a more detailed answer about that here: how-can-i-change-the-textual-representation-displayed-for-a-type-in-swif.
Lastly, you mention that when you loop trough "t" and display the username in the console it does not display anything. This is caused by one of two things:
Because there are no users being returned from parse, so the "t" array is actually empty. Try print(t.count) to see how many objects are in the array.
Because your "Users" object declares an empty string "" as the default username and the username is not being set correctly when getting the data from the parse. Which means that it IS actually printing something, just that it is an empty string. Try defining a different default value like var username : NSString = "Undefined" to see if it prints something.
Good luck learning swift!

Dynamic table names in Entity Framework linq

I'm using Entity Framework 6 with ASP.Net MVC 5. When using a database context object, is there a way to use a variable for the table name, without having to manually write the query?
For example:
var tableName = "NameOfTable";
result = context.tableName.Find(...);
I know that particular code won't work, because tableName is not defined in context, but is there a way to achieve the desired effect?
There are some similar questions on this site, but they never really solved the problem and they were for earlier versions of entity framework, so I'm hoping that there is an answer now.
Here's a simple solution using a switch to associate a particular Type to a table. You could also maintain use some sort of Dictionary<string, Type> object.
var tableName = "Table1";
// Get proper return type.
Type returnType;
switch(tableName) {
case "Table1":
returnType = typeof(Table1EntityType);
break;
case "Table2":
returnType = typeof(Table2EntityType);
break;
}
var query = context.Set(returnType);
// Filter against "query" variable below...
var result = query.Where(...);
-or-
var tableName = "Table1";
Dictionary<string, Type> tableTypeDict = new Dictionary<string, Type>()
{
{ "Table1", Table1Type },
{ "Table2", Table2Type }
};
var query = context.Set(tableTypeDict[tableName]);
// Filter against "query" variable below...
var result = query.Where(...);
EDIT: Modified for Entity Framework
EDIT2: Use typeof per #thepirat000 's suggestion
In addition to the helpful answers above, I also want to add this in case it helps someone else.
If you are getting this error on the "Where" clause in Mark's answer:
'DbSet does not contain a definition for 'Where' and no acceptable extension method 'Where' accepting an argument of the type 'DbSet' could be found.
Installing the Nuget Package "System.Linq.Dynamic.Core" made the error disappear for us.
If you need to access the LINQ methods and the column names from the table, you can code something like this:
var tableName = "MyTableName";
var tableClassNameSpace = "MyProject.Models.EntityModels";
using (var dbContext = new MyEntities())
{
var tableClassName = $"{tableClassNameSpace}.{tableName}";
var dynamicTableType = Type.GetType(tableClassName); // Type
var dynamicTable = dbContext.Set(dynamicTableType); // DbSet
var records = dynamicTable
.AsQueryable()
.ToDynamicList()
.OrderBy(d => d.MyColumnName)
.Select(d => new { d.MyColumnName })
.ToList();
// do stuff
}

EF4 adding multiple entities (An object with the same key already exists in the ObjectStateManager)

I have a object with a lot of properties on it. A bunch of these large object are to be inserted in the db but with only one property on them changing. The property that will be changing is not the primary key. First time SaveChanges succeeds but the subsequent ones fail with "An object with the same key already exists in the ObjectStateManager.....". Here is the flow in code:
//create the entity and set the properties that don't change
TheLargeObject obj = new TheLargeObject();
obj.Prop1 =
obj.Prop2 =
...
obj.Prop20 =
//create a list of values that differ between each entity
List<int> validIds = new List<int>();
private static void SaveToDatabase(TheLargeObject obj, List<int> validIds)
{
foreach (int id in validIds)
{
//this is the only property that changes
obj.KeyId = id;
//make a copy - do we really need this?
TheLargeObject newobj = new TheLargeObject();
newobj = obj;
using(Entities objContext = new Entities())
{
objContext.TheLargeObjects.AddObject(newobj); //ERROR: An object with the same key already exists in the ObjectStateManager.
objContext.SaveChanges();
}
}
}
I'm just starting out with EF4, so I'm probably going about this in the wrong way.
Thanks
I'm not sure what your trying to do here. Mainly this statement confuses me:
A bunch of these large object are to be inserted in the db but with only one property on them changing.
How can a new object (ie inserted) be changing? If it's new, what is there to change?
All of the entities in your model have an EntityKey, which is usually the primary key on the database-side.
What i think your doing is doing .AddObject, when you should be doing .Attach.
Here's how you INSERT a new object:
var newFoo = new Foo();
ctx.Foos.AddObject(newFoo);
newFoo.SaveChanges();
Here's how you UPDATE an existing object:
var existingFoo = ctx.Foos.SingleOrDefault(x => x.Id == 1); // or however you want to get it
existingFoo.Name = "Changed foo";
newFoo.SaveChanges();
Or if you have a detached entity:
var existingFoo = new Foo();
existingFoo.Name = "Foo name";
ctx.Foos.Attach(existingFoo);
ctx.SaveChanges();
So, i think in your example, your code should simply be:
objContext.TheLargeObjects.Attach(newObject);
objContext.SaveChanges();
In a nutshell, if you have an entity which you are positive already exists in the database, and you have constructed the entity manually, use .Attach. If you have a brand spanking new object, use .AddObject.
However, to be safe - you could go and get the object again, make the changes you need, then do .SaveChanges().
.Attach is usually used in stateless scenarios such as web sites, where objects are not kept in the graph between requests, therefore to make changes we need to .Attach, or retrieve the object again before making the changes.
Hopefully this clears it up for you.

Resources