Entity framework finding foreign keys - entity-framework

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();

Related

EF Core equivalent of ObjectContext.MetadataWorkspace

We previously (i.e., in EF 6) used the following code to obtain all enum properties which are used in any entity or complex type in our EF model:
var metadataWorkspace = ((IObjectContextAdapter) context).ObjectContext.MetadataWorkspace;
var enumTypes = metadataWorkspace
.GetItems<StructuralType>(DataSpace.OSpace)
.SelectMany(t => t.Members)
.OfType<EdmProperty>()
.Where(m => m.EnumType != null)
.Select(m => m.EnumType)
.Distinct()
.ToList();
What is the EF Core equivalent of this? How to access "all types" in the model?
Is the following correct and complete (i.e., not missing owned types or anything like that).
var enumTypes = context.Model.GetEntityTypes()
.SelectMany(et => et.GetProperties())
.Where(p => p.ClrType.IsEnum)
.Distinct()
.ToList();

Entity Framework How To Load Primary Key Only

Is it possible to load only specific attributes of a class, such as only the primary key, without fetching the other attribute values?
I need to get an object from the DB but only have the ID value populated, all other attributes are not needed.
If another attribute is requested, the rest of the object needs to be loaded.
Yes you can and technique is called "Projection"
e.g.
var filteredData = context.Entity
.Where(p => p.ID == 1 ) // just an example filter
.Select(p => new Entity
{
ID = p.ID,
})
.ToList();
If if helps dont forgot to vote and mark it as answer :)

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 primary key name

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);

Why are anonymous Types in EF4 different from LINQ to SQL ones?

I have the following query in LINQ to SQL to fetch all records from a Table that are not already in a jointable.
// <param name="id">The ID of the Person</param>
IEnumberable<object> GetUnassignedClients(int id)
{
_db.Clients
.Select(i => new
{
Client_id = i.Id,
Person_id = id,
Cid = id + "." + i.Id // Please don't ask why I do this. I just have to do it
// ... some more fields
})
.Where(o =>
!_db.Clients_Persons
.Where(t => t.Person_id == id)
.Select(t => t.Client_id)
.Contains(o.Client_id))
.Distinct().ToList();
}
Now I have started a migration to EF4 but the "Cid" part of the anonymous type with the combination ToList() (ToList() triggered the exception is a simplified testcase without the WHERE condition) fails with the exception:
Unable to create a constant value of
type 'System.Object'. Only primitive
types ('such as Int32, String, and
Guid') are supported in this context.
Why is that so or am I missing something here?
EF does not know how to translate the expression id + "." + i.Id into valid SQL which is why it fails. You have to tell EF that it needs to convert id from an integer to a string. You can do this using the SqlFunctions class in the following way:
var ret = _db.Clients
.Select(i => new
{
Client_id = i.Id,
Person_id = id,
Cid = SqlFunctions.StringConvert((double) id) + "." + SqlFunctions.StringConvert((double) i.Id) // Please don't ask why I do this. I just have to do it
// ... some more fields
})
.Where(o =>
!_db.Clients_Persons
.Where(t => t.Person_id == id)
.Select(t => t.Client_id)
.Contains(id)
)
.Distinct()
.ToList()
;