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