Entity Framework primary key name - entity-framework

I have created an entity model. I want to get the primary key name (i.e. property name) when I pass the entity name at runtime. Is it possible?

It is possible with entity type:
var objectSet = objectContext.CreateObjectSet<YourEntityType>();
var keyNames = objectSet.EntitySet.ElementType.KeyMembers.Select(k => k.Name);
or with entity type name:
var workspace = objectContext.MetadataWorkspace;
var entityType = workspace.GetItems<EntityType>(DataSpace.CSpace)
.FirstOrDefault(e => e.Name == yourEntityTypeName);
var keyNames = entityType.KeyMembers.Select(k => k.Name);

Related

How to convert IQueryable complex type to generic list in entity framework

IQueryable<SystemGroup> systemGroupQuery;
systemGroupQuery = dbContext.SystemGroups.Select(x => new SystemGroup()
{
Id = x.Id,
Name = x.Name,
SmsAccountId = x.SmsAccountId,
SmsAccount = dbContext.SmsAccounts.Where(g => g.Id
== x.SmsAccountId).SingleOrDefault()
});
var systemGroups = systemGroupQuery.ToList();
While converting to list i am getting the error "The entity or complex type 'Models.Context.SystemGroup' cannot be constructed in a LINQ to Entities query."
Add .ToList() before .Select
or
use anonymous object and map it after .ToList()
Linq to entities doesnt allow constructing complex typed objects in the fly

Seeding a Database with Code First Entity Framework - Foreign key syntax

I am trying to find the correct syntax to seed a database with test data. I have a foreign key to my product table. It is the category. I have seeded the database with the values for categories, but stuck on how to add that relationship to the product. I have tried this way to no avail.
context.Categories.AddOrUpdate(x => x.Name,
new Category
{
Name = "Fruit"
});
context.Products.AddOrUpdate(x => x.Name,
new Product
{
Name = "Cherries",
Description = "Bing Cherries",
Measure = "Quart Box",
Price = 1.11M,
Category = context.Categories.FirstOrDefault(x => x.Name == "Fruit")
}
});
Can anyone point me in the right direction?
I found that in order to accomplish the foreign key from Category is to do a save changes to the context. Then I was able to query the context for the categoryId and save it to the CategoryId on the product.
context.Categories.AddOrUpdate(x => x.Name,
new Category
{
Name = "Fruit"
});
context.SaveChanges();
context.Product.AddOrUpdate(x => x.Name,
new Product
{
Name = "Cherries",
Description = "Bing Cherries",
Measure = "Quart Box",
Price = 1.11M,
CategoryId = context.Categories.FirstOrDefault(x => x.Name == "Fruit").Id
});

Entity framework finding foreign keys

I want to find all the foreign keys of an entity in my entity model.
I have used the following to get a list of all the properties for an entity:
var workspace = _entities.MetadataWorkspace;
var entityType = workspace.GetItems<EntityType>(DataSpace.CSpace).FirstOrDefault(e => e.Name == tablename);
var keyNames = entityType.Members.Select(k => k.Name);
Is there any way to find only those properties which have foreign key associations? And also that property in the reference entity with which it is associated?
I worked out the solution:
var fk = _entities.MetadataWorkspace
.GetItems<AssociationType>(DataSpace.CSpace)
.Where(a => a.IsForeignKey);
// Check if the table has any foreign constraints for that column
var fkname = fk
.Where(x => x.ReferentialConstraints[0].ToRole.Name == tablename)
.Where(x => x.ReferentialConstraints[0].ToProperties[0].Name == columnname);
// Get the corresponding reference entity column name
var refcol = fkname
.Select(x => x.ReferentialConstraints[0].FromProperties[0].Name)
.First();

Entity Framework - How to Set Association Value?

Let's say I have a Person class and an Order class, with foreign keys in the DB. The EF model will mark Person with a List of Orders and Order with a Person instance.
If I want to set the Person for the Order, do I really have to do it with an instance of Person?
Is there not a slimmed down way to do so, say with just a PersonID ?
To assign Person entity to a Order without loading Person entity, you have to do something like this:
var db = new OneToManyEntities();
var Order = new Order { OrderId = 100, OrderName = "Order name" };
Order. PersonReference.EntityKey = new EntityKey("OneToManyEntities.Person ","PersonID",10);
db.AddToOrders(Order);
db.SaveChanges();
Puzzled's answer is correct for EF v1. It's a pain. If you don't mind the extra query, you can set the property succinctly:
int id = 1;
Order.Person = context.Persons.Where(x => x.PersonID == id).FirstOrDefault();
Entity Framework v4 will have "FK Associations", which is a fancy term for directly-settable foreign keys.

What is the way to make a select on a nullable foreign key field in Entity Framework?

I have a category table which has a foreign key to it self by a nullable parentId field. In Entity-Framework when a relation is created, the entity is generated without any relation fields. I mean, in my example when I created a parentId-Id relation in Category table, the generated Category Entity will have an int typed Id property and a Category typed ParentCategory property and no ParentId property. And this makes my queries harder.
So, I have a trouble when I want to select the subcategories of a category. I use the method below for that;
public IEnumerable<ICategory> GetSubCategories(long? categoryId)
{
var subCategories = this.Repository.Category.Where(c => c.ParentCategory.Id == categoryId)
.ToList().Cast<ICategory>();
return subCategories;
}
But this does not work, when I want to select the root categories. What is the way of doing this?
By the way, I wonder if there is a way to generate entities like in Linq to Sql, with an int typed Id property, an int typed ParentId and a Category typed ParentCategory property.
To select the root categories:
var rootCategories = this.Repository.Category.Where(c => c.ParentCategory == null).ToList().Cast<ICategory>();
To generalize the code to work with both sub & root categories:
var rootCategories = this.Repository.Category.Where(c => categoryId == null ? c.ParentCategory == null : c => c.ParentCategory.Id == categoryId).ToList().Cast<ICategory>();