Migration didn't pluralize table name - entity-framework

I added a simple class MemberModel and added the following to my database context class:
public DBSet<MemberModel> Member { get; set; }
After adding migration and updating the database, the table name generated is Member and not Members. Where did I go wrong?

EF Core will use the name of the DbSet property. Rename Member to Members should result in a Members table.
public DBSet<MemberModel> Members { get; set; }
more info
https://github.com/aspnet/Announcements/issues/167

Related

Entity Framework 7 Include() not working as expected

EF7 fills contained navigation properties even when not requested. For example, I have the below entities.
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string Gender { get; set; }
public int DepartmentId { get; set; }
public Department Department { get; set; }
}
public class Department
{
public int DepartmentId { get; set; }
public string Name { get; set; }
public ICollection<Employee> Employees { get; set; }
}
My fetch query is as below.
ctx.Employees.Where(e => e.Gender == "Male").Include(e => e.Department)
I get Department property of Employee object filled – which is as expected as I have an Include for Department. I find that Department.Employees is also filled but partially (only with male employees). I have not specified an Include for Department.Employees, but it is still getting populated. Is this behavior by design? Is there any way to avoid fetching Department.Employees in this scenario?
I am using EF7 NuGet package with version 7.0.0-rc1-final.
That is the normal behavior of EF. When you execute your query, all the entities you load is going to be attached to your context. So, EF is not executing another query and loading Department.Employees partially, those employees were loaded earlier when you execute your query. In summary, when you consult Department.Employees navigation property, EF is going to fill that property with the employees that you load with your query filtering by Gender.
Update:
As I pointed out in my comment above, Lazy Loading is not supported in EF7. If you want to avoid that Json.NET serializes that property, you can use the attribute JsonIgnore over that property or you can create a custom class (DTO) to project your query and fill only the properties that you need. I also recommend take a look to Automapper if you decide to use this last solution.

EF7 Scaffolding not creating columns

I have a model that looks like this:
public class Order
{
// removed irrelevant other properties
public Guid Id { get; set; }
public Address BuyerAddress { get; set; }
public Address SellerAddress { get; set; }
}
public class Address
{
public Guid Id { get; set; }
public string Street { get; set; }
public Order Order { get; set; }
}
In the DbContext I hooked them up like this:
entityTypeBuilder.HasOne(x => x.BuyerAddress).WithOne(x => x.Order).IsRequired(false);
entityTypeBuilder.HasOne(x => x.SellerAddress).WithOne(x => x.Order).IsRequired(false);
When I run
dnx ef migrations add Foo
dnx ef database update
The table is being created with some of the properties, but other properties, like the SellerAddress are missing (the BuyerAddress is being created fine though).
The same problem for other entities, such as User <-> BankAccount which is a 1:1 relationship that is defined as entityTypeBuilder.HasOne(x => x.BankAccount).WithOne(x => x.User).IsRequired(false);
Does anyone know what's up? I'm using Entity Framework 7.0.0-rc1-final. The issue is driving me crazy.
I fixed the problem. First I had foreign key properties, so my models looked like this:
public Order Order {get;set;}
public Guid OrderId {get;set;}
I didn't like this, and it resulted in duplicate columns in the database, so I removed the [EntityName]Id properties from my model. But because of this, EF got all confused could not longer figure out what I was trying to do. So for all 1:1 relationships I simply removed the navigation property on one side of the equation (so now Order has a reference to an Address, but Address no longer has a navigation property back to Order). This solved the problem.
So in case of the sample code in my question, I removed the Order property from Address.

How to correctly build EF5 Code-first model with two or more lists that relate to the same child table?

I have the following models:
public class SomeForm
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public IList<FacilityContactInformation> OriginatingFacilities { get; set; }
public IList<FacilityContactInformation> DestinationFacilities { get; set; }
}
public class FacilityContactInformation
{
public FacilityContactInformation()
{
Id = -1;
}
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[MaxLength(50)]
public string Owner { get; set; }
}
I am using automatic migrations to gen and re-gen the database schema.
This generates the error "Foreign key 'FK_dbo.FacilityContactInformations_dbo.SomeForm_SomeForm_Id ' references invalid column 'SomeForm_Id' in referencing table 'FacilityContactInformations'.
Could not create constraint. See previous errors.
I suspect the root cause is that EF tries to generate a FK FK_dbo.FacilityContactInformations_dbo.SomeForm_SomeForm_Id for both lists
Is there any way to keep using automatic migrations, but get this to generate a FK that works? It would seem like the FK should include the list name and generate two properties on FacilityContactInformations OR should generate an intermediate table to join on.
When you have 2 navigational properties that link to the same class, you should override OnModelCreating method of your dbcontext class. Then add this code into the OnModelCreating:
modelBuilder.Entity<SomeForm>
.Hasmany<FacilityContactInformation>(x => x.OriginatingFacilities);
modelBuilder.Entity<SomeForm>
.Hasmany<FacilityContactInformation>(x => x.DestinationFacilities);
This is because EF cannot determine the correct keys if the nav. prop. link to the same class.

Entity Framework 1 to 1 relationship using code first. how?

I have two classes. How can I turn these two classes into a one to one relationship using the entity framework code first method?
public class Region
{
public int RegionId { get; set; }
public string Name { get; set; }
public virtual Factory _factory { get; set; }
}
public class Factory
{
public int FactoryId { get; set; }
public string Name { get; set; }
public virtual Region _region { get; set; }
}
When I try this, I get this error:
Multiplicity is not valid in Role 'Region_Factory_Source' in relationship 'Region_Factory'. Because the Dependent Role properties are not the key properties, the upper bound of the multiplicity of the Dependent Role must be '*'.
This occurs in CodeFirst because of the virtual keyword. In effect, you are creating a relationship where creating one item requires the creation of the other. however, the virtual keyword allows lazy instantiation, which means that creating an object of one type doesn't automatically create the other type, allowing the Id on the foreign item to be null. This implies a 0..1 relationship, but since each side is virtual, what you get is a 0..0 which isn't allowed.
There are 2 methods which you can use to remedy the situation.
remove the virtual option from either one side or both sides of the navigation properties, allowing for a 0..1 or a 1..1 map.
explicitly add a property for the Foreign key from the other entity on each object. i.e. on class Region add a property for FactoryId and on Factory add a property for RegionId
There are other ways to help Entity Framework determine which object is the Dependent Object, i.e. using Entity Framework Fluent api.
from MSDN
Configuring a Relationship Where Both Ends Are Required (One-to-One)
In most cases the Entity Framework can infer which type is the dependent and which is the principal in a relationship. However, when both ends of the relationship are required or both sides are optional the Entity Framework cannot identify the dependent and principal. When both ends of the relationship are required, use WithRequiredPrincipal or WithRequiredDependent after the HasRequired method. When both ends of the relationship are optional, use WithOptionalPrincipal or WithOptionalDependent after the HasOptional method.
the following code would create a Principal Factory with a Dependent Region
// Configure the primary key for the Region
modelBuilder.Entity<Region>()
.HasKey(t => t.RegionId);
modelBuilder.Entity<Factory>()
.HasRequired(t => t.Region)
.WithRequiredPrincipal(t => t.Factory);
EF6, add attributes:
[Key]
public int RegionId { get; set; }
[Key, ForeignKey("Region")]
public int FactoryId { get; set; }

entity framework navigation property to table in different db

I have 2 tables in different db
db1..Towns
id
Nazv
db2..MathchedTown
id
t_id
d_name
They are joined by по Towns.id = MathchedTown.t_id
This EF classes:
[Table("Towns")]
public class Town
{
[Key]
public int id { get; set; }
public string Nazv { get; set; }
}
[Table("MathchedTown")]
public class mTown
{
[Key]
public int id { get; set; }
[Required]
public string t_id{ get; set; }
[Required]
public string d_name{ get; set; }
[ForeignKey("t_id")]
public virtual Town town { get; set; }
}
when i try to get item.town.nazv i get error:
Invalid object name 'dbo.Towns'.
If i change [Table("Towns")] to [Table("db1.dbo.Towns")], then appear almost the same error: Invalid object name 'dbo.db1.dbo.Towns'.
That all errors are SqlExceptions
How i can talk EF4 don't substite the "dbo." prefix?
Entity framework does not support multiple databases in a single context. But it supports multiple schemas in a single database. If you do not specify the schema it will assume dbo.
[Table("Towns", "MySchema")]
public class Town
You can specify the schema as above.
If you want to use a table in a different database you can create a view to that table in your database. But it will be read only.
Unfortunately EF4 does not support navigation property that is in other db.
You have two choices.
One, create a stored procedure and import it as a function in edm. And genetate complex type for the return result.
Two, create two entity models for each database. And run a query for a database then run the other query to the other database with where clause from the first query result.