Entity Framework Code First connection to a database

Connection String

  <connectionStrings>
    <add name="<my>Entities"
connectionString="Data Source=<servername>;
initial catalog=<dbname>;
integrated security=True;
multipleactiveresultsets=True;
App=EntityFramework;"
providerName="System.Data.SQLClient" />
  </connectionStrings>

Database Class

Imports System.Data.Entity

Public Class myDatabase
    Inherits Entity.DbContext

    Property Products() As DbSet(Of Products)
    Property Logs() As DbSet(Of myLog)

    Sub New()
        MyBase.New("EFIEntities")
    End Sub

    Protected Overrides Sub OnModelCreating(ByVal modelBuilder As DbModelBuilder)

        modelBuilder.Entity(Of Products).Map(Sub(mc) mc.ToTable("Product.Products"))

        modelBuilder.Entity(Of myLog).Map(Sub(mc)mc.ToTable("dbo.Logs"))

        modelBuilder.Entity(Of IHead)().Property(Function(f) f.OrderCreated).
                   HasColumnName("ih_date")

        modelBuilder.Entity(Of Film).Ignore(Function(f) f.ColumnNotInDB)

	'For Composite Key
	modelBuilder.Entity(Of RouteCardOpsProduct).
		HasKey(Function(f) New With {f.ProductID, f.OpOrder})

        modelBuilder.Entity(Of ComponentCF).Property(Function(f) f.ProductID)
		.HasDatabaseGeneratedOption(ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None)

'Creating Foreign Keys with thanks Julie Lerman
Note: this is tricky and easily broken with the wrong syntax.
Instead before doing the below consider a LINQ statement which would use navigation properties which work surprisingly well
Dim result = From c In context.Customers Where c.ID = 14 Select New With {c, c.Quotes}  'Anonymous type
To return this as a customer do this:
        Function FindCustomerIncludeQuotes(CustomerIDValue As Integer) As Customer
            Dim query = (From c In context.Customers
                         Where c.ID = CustomerIDValue
                         Select New With {c, c.Quotes}).FirstOrDefault

            Dim result = query.c
            result.Quotes = query.Quotes
            Return result
        End Function

'http://msdn.microsoft.com/en-us/data/gg194009
'http://msdn.microsoft.com/en-us/data/hh134698.aspx
	modelBuilder.Entity(Of Post)().HasRequired(Function(p) p.Blog).WithMany(Function(b) b.Posts).HasForeignKey(Function(p) p.FKBlogId)

	modelBuilder.Entity(Of Post)().HasMany(Function(p) p.Tags).WithMany(Function(t) t.Posts).Map(Sub(mc)
				mc.ToTable("PostJoinTag")
				mc.MapLeftKey("PostId")
				mc.MapRightKey("TagId")
			End Sub)

     End Sub End Class

Classes

Public Class Products
    <key> Public Property ID As Integer
    Public Property Code As String
End Class

Public Class RouteCardOps
	'Composite key do mapping in OnModelCreating. Column may not work yet in EF v4.x
	<key> Property ID As Integer
	<key> Property OpOrder As Integer
	Property OpCode As String

	Overridable Property Product As Product
End Class

Public Class PadCost
    <key, DatabaseGenerated(DatabaseGeneratedOption.None)> Property PadID As Integer
    <DatabaseGenerated(DatabaseGeneratedOption.Computed)>Property Total SMV As Decimal
End Class

Public Class Blog
 	<key> Property ID As Integer
	Property Title As String
End Class

Public Class Posts
	<key> Property ID As Integer
	Property Title As String
	Property BlogID As Integer

	Overidable Property Blog As Blog
End Class

Program

Module Module1
Sub Main()

Dim db As New myDatabase

Dim resultProduct = From a In db.Products
Where a.Code = "abc"
Select a

Dim result = From a In db.Logs Select a Take 10

Console.WriteLine(String.Concat("Log ID: ", result.First.ID))
Console.WriteLine(String.Concat("Product ID: ", resultProduct.First.ID))
Console.WriteLine()
Console.WriteLine("Press a key to continue/end")
Console.ReadKey()

'To Execute SQL directly against the database
context.Database.ExecuteSqlCommand("DELETE FROM Product.Products WHERE ID = ", 1)

'Then you may need to instantiate a new copy or clear an existing copy use context.Set(Of <entity>)
contextCF.Products = contextCF.Set(Of Products)()
End Sub

End Module

Windows Forms

http://msdn.microsoft.com/en-us/data/jj682076.aspx

Imports System.Data.Entity

now
	context.MyEntity.Load()
	MyBindingSource.DataSource = context.MyEntity.Local.ToBindingList

was
    'context.Currency.Load()
    DbExtensions.Load(context.Currency)
    Me.CurrencyBindingSource.DataSource = DbExtensions.ToBindingList(context.Currency.Local)

Errors and solutions:

Error Unable to load the specified metadata resource
Solution: For code first the metadata=res is unnecessary. Just use an ordinary connection string as above.

Error: ‘Load’ is not a member of System.Data.Entity.DbSet(Of …)
Solution:
Use Imports System.Data.Entity
Also ensure there is a reference to EntityFramework in the project. Especially if this is an N-Tier solution

Error: With Inherited class even it is the parent class that is being collected. Then get Invalid column name ‘Discriminator’
Solution Add <NotMapped> to child class
modelBuilder.Ignore<classname>();

Error: INSERT does not insert key if this is not an IDENTITY
Solution: Add attribute as <key, DatabaseGenerated(DatabaseGeneratedOption.None)>
Or modelBuilder.Entity<Address>().Property(p => p.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

Error: After a delete using context.Database.ExecuteSQLCommand(“DELETE…”) the context still have copies of the entities in any DBSet which needs to be cleared
Solution: context.Products = context.Set(Of Products)()

Error: The type initializer for ‘System.Data.Entity.Internal.AppConfig’ threw an exception
Solution:
If Entity Framework is installed by NuGet then you should not have a problem. However after a version update, or manual changes you may get this fault. One problem may be that in the App.Config file the section name may be missing as below:

<configuration>
    <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
      <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
    </configSections>

Error:
The Entity Framework provider type ‘System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer’ registered in the application config file for the ADO.NET provider with invariant name ‘System.Data.SqlClient’ could not be loaded. Make sure that the assembly-qualified name is used and that the assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.

Solution:
Add reference to EntityFramework.SqlServer, which may have not been installed via NuGet for some reason
Or if new then it may not have been built properly, so try building project again.
See link in error or: http://msdn.microsoft.com/en-us/data/jj730568

End

Entity Framework – Inheritance/Association – including Troubleshooting and comment on verbose SQL

See this video on Model Table Per Type

http://msdn.microsoft.com/en-us/data/cc765425.aspx

  1. Update Model from Database – Add Table
  2. Right-click Entity Add Inheritance
  3. Error 11009: Property ‘<>’ is not mapped
  4. Right-click Entity > Table Mapping > re map missing
  5. Running transformation: A member named ID cannot be defined in class DerivedClass. It is defined in ancestor class ParentClass.
  6. Delete it from DerivedClass

Error 3027: No mapping specified for the following EntitySet/AssociationSet – TableATableB

Error 11008: Association TableATableB is not mapped
EF is not expecting both a Foreign Key relationship and an association, see note at top of: http://msdn.microsoft.com/en-us/library/bb738488.aspx
Delete the association

Existing queries may then break as the Entity type no longer exists. So in my case Products is base type PadMain inherits from this. Used to have PadMains now PadMain EntityName is Products, so query on PadMains needs to change. From/To:

From b In context.PadMains
From b in context.Products1.OfType(Of PadMain)()

However if PadMain has subtypes then the SQL generated is verbose. If table is separated out in SQL then you just want the base table. If a field will appear in multiple related child tables then you will get duplications. In this scenario this is a major disadvantage of Entity Framework. Hopefully it will be fixed in future. For now I have removed my inheritance.

LINQ and Entity Framework with DbContext – Convert Anonymous type to Strongly Typed – Bind to ListBox

[ Personally I have a sample of this in EFSample1.sln ]
To convert anonymous type to strongly typed, you can add a class that does what you want, then Select New … with {.ID = …}
This allows you to say get data from more than one table and still have a strongly typed output. Will not be updateable.

To fill a ListBox use

Imports System.Linq ‘if namespace not already imported

See http://wp.me/p17IS4-9S

Dim result = …GetEmployees
ListBox.DataSource = result.ToList

To save on setting the DisplayMember use .ToString in the class

Public Class EmployeeList
Property ID As Integer
Property FullName As String

Overrides Function ToString() As String
Return FullName
End Function

End Class

Public Class EmployeeEF

Private context As New EFWinFormsDBContext.TestEFIEntities

Function GetEmployees() As System.Linq.IQueryable(Of EmployeeList)

Dim result = From emp As Employee In context.Employees Join con As Contact In context.Contacts On emp.EmployeeID Equals con.ID Order By con.FullName
Select New EmployeeList With {.ID = emp.EmployeeID, .FullName = con.FullName}

Return result

End Function

End Class

Deleting an ASP.Net azure hosted website using Entity Framework can potentially delete the linked database

I had a database on Azure that was being updated using Windows Forms. I then created an ASP.Net MVC application using EF to work against the same database. However I following a tutorial which used Code First

http://www.windowsazure.com/en-us/develop/net/tutorials/web-site-with-sql-database/

This would not publish until I used Nu-Get to:

enable-migrations

However I think I then used code first migrations on publish. However I published the website with high credentials and wanted to change the credentials to lower. Could not see how to do this in Azure, so deleted the website. At this point the database disappeared without warning.

This is why the last posts have been about SQL Azure backup. However recovered using on-site data and re-created database.

Microsoft support helped with the ASP.Net so:

enable-migrations

Check the file created, but do not check the box on publish.

Tested by deleting the Website – This then asked if you wanted to delete the linked database. Answer: No. Database stays ok.

Entity Framework EntityState context.Entry().State

Entity Framework EntityState

context.Entry(<object>).State

http://blogs.msdn.com/b/adonet/archive/2011/01/29/using-dbcontext-in-ef-feature-ctp5-part-4-add-attach-and-entity-states.aspx

http://msdn.microsoft.com/en-us/library/system.data.entity.infrastructure.dbentityentry(v=vs.103).aspx

Error 3031: Problem in mapping fragments starting at line… nullable column

Error 3031: Problem in mapping fragments starting at line… nullable column

In SQL I added a column to a table and initially had the column as Not Nullable. I then updated a view to use the new column. I then updated Entity Framework model from the database. I then changed my mind and made the column nullable. I then updated EF model once again and it would not compile. No-manner of updating column Nullable properties worked.

After some reading suggested this was a bug in EF. As a precaution I updated the view in SQL to refresh the schema went to EF and removed and added it again.

Entity Framework possible feedback to Microsoft Connect – IBindingListView

 

https://connect.microsoft.com/data/feedback/details/704105/entity-framework-winforms-datagridview-support-for-bindingsource-filter-sort-and-column-heading-sort

 

Entity Framework WinForms DataGridView support for BindingSource.Filter .Sort and column heading Sort

Entity Framework looks useful and I have limited use of it in my code. Also several developers have expressed to me how they have found it useful.

I currently use a lot of WinForms databinding using DataSets and BindingSource. Out of the box I get column header sorting. Also it is a simple matter to set BindingSource.Filter and BindingSource.Sort as strings. I have used this feature to provide a lot of data-driven filter and sort strings for UI quick filter and sort which works very well.

However when I use Entity Framework the column header sort and BiningSource.Filter and .Sort properties do not work. My understanding is that this is because EF does not support IBindingListView. Although it might but not out of the box. Please advise or consider implementing this in future editions of Entity Framework.

Thank you

Stephen, UK

Entity Framework: Stored Procedure – Function import

How to…get a stored procedure from SQL and use it in code
In this case execute only, not entity CRUD

  1. Model Browser 
  2. Stored Procedure
  3. Right-click
  4. Update Model from database
  5. Get your stored procedure
  6. However at this point still unusable in code
  7. Not obvious step > Double click Stored Procedure
  8. Choose function import options
  9. OK creates function import which is then useable in code
  10. Note all parameters are surpisingly nullable – May be there is a way preventing this. Unsolved

 

Enjoy !

Entity Framework: WinForms databinding in EF4.1 – DBSet

Solved

Dim context As New SOPEntities
System.Data.Entity.DbExtensions.Load(context.Employees.Where(Function(f) f.Current = True).OrderBy(Function(g) g.FullName))
EmployeeBindingSource.DataSource = context.Employees.Local
ListBox1.DataSource = System.Data.Entity.DbExtensions.Tobindinglist(context.Employees.Local)
ListBox1.DisplayMember = “FullName”

Problem

‘local’ is not a member of ‘System.Data.Objects.ObjectSet(Of <entityname>)’

See http://wp.me/p17IS4-ih

 

Solved

Open the <Name>Model.edmx > Right click > Add code generation item…

Choose ADO.Net DbContext Generator. This has affect of changing the .edmx file Code Generation Strategy to “None” and creates a text template model and .Local now works.

Discussion

Uses EF4.1 EntityFramework.dll
Database first, then add code generation item to get T4 simpler classes and DBSet inherits DBContext
Initially could not work out how to get the Load method. See above for solution.
There is no MSDN VB.Net sample yet. The C# is more like context.Employees.Local.ToBindingList. So it took me a while to work out the syntax above.

Unsolved:
Also the FullName is now a computed column in the database. Was unable to work out how to do this in EF. It may come in the future as a “Model Defined Function”. Do not think this is a Scalar or Complex Type which is something else.
Unsolved:
For BindingSource to support complex filter it needs to support IBindingListView. Typically EF does not.

Links

Binding Objects to Controls
http://msdn.microsoft.com/en-us/library/gg197521(v=VS.103).aspx

Following is in C#
http://msdn.microsoft.com/en-us/library/gg197523(v=VS.103).aspx

Entity Framework: Generating Strongly Typed Entity Classes: Lightweight

Lightweight

Step by step here: http://msdn.microsoft.com/en-us/data/gg685494

Videos here:  http://msdn.microsoft.com/en-us/data/aa937723