I am new to MVC, and right now I am trying to work out the example demonstrated in professional Asp.Net MVC 4 by Galloway J and others, in this example I have to do the following :
create 3 classes: Album, Genre, Artist
create DBContext class called MusicStoreDB
create a controller call it store manager.
in the scaffolding options I used MVC controller with read/ write actions and views, using Entity framework
I also set an Initializer to recreate the database always on application start
but when running the solution no database created, what could be the problem I have tried lot of suggestions, even reinstalling the sql server 2008 R2 and, VS 2012 but it dose not work.
this is the global.asax file
Imports System.Web.Optimization
Imports System.Data.Entity
Public Class MvcApplication
Inherits System.Web.HttpApplication
Sub Application_Start()
AreaRegistration.RegisterAllAreas()
Database.SetInitializer(Of MusicStoreDB)(New DropCreateDatabaseAlways(Of MusicStoreDB)())
WebApiConfig.Register(GlobalConfiguration.Configuration)
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters)
RouteConfig.RegisterRoutes(RouteTable.Routes)
BundleConfig.RegisterBundles(BundleTable.Bundles)
AuthConfig.RegisterAuth()
End Sub
End Class
and the MusicStoreDB class
Imports System.Data.Entity
Public Class MusicStoreDB
Inherits DbContext
Public Property Albums() As DbSet(Of Album)
Get
End Get
Set(value As DbSet(Of Album))
End Set
End Property
Public Property Genres() As DbSet(Of Genre)
Get
End Get
Set(value As DbSet(Of Genre))
End Set
End Property
Public Property Artists() As DbSet(Of Artist)
Get
End Get
Set(value As DbSet(Of Artist))
End Set
End Property
End Class
Make sure your DbContext specifies the proper connection string:
public class MyNewContext : DbContext
{
public MyNewContext() : base("DefaultConnection")
{
}
public DbSet<Genre> Genres { get; set; }
public DbSet<Artist> Artists { get; set; }
public DbSet<Song> Songs { get; set; }
}
It is DefaultConnection by default, but make sure you changed yours to MusicStoreDB if you want to use your new connection string. I have left mine at default thus far and deployed to Azure effortlessly.
You should be able to use Entity Framework in a new project without setting up any new connection strings. It "just works" using SQL Express.
I'm willing to bet you have a database existing if you connect to (localdb)\v11.0 in SSMS or elsewhere.
Post your global.asax and DbContext if you continue to have problems.
So I faced this same problem today and it turns out that I presumed EF automatically checks on application start whether that DB exists or not; to say the least my hope was way to ambitious.
The EF will only create the DB if it doesn't exist once you invoke the DB context. For example when you first run the application, if on the landing page you don't instantiate the DB context nothing happens.
For the Music Store example if you are following the book, navigate to (using your own port number of course) "http://localhost:34295/StoreManager", that controller's action should instantiate the DBContext if you have been following the book.
Hope this helps anyone who got a little lost like me!
Related
My module is a page directory to strongly type pages in a large ASP.Net webforms application using VB.Net.
Public Module PageDirectory
Public Module Sub
Private _subDirectory As String = "/sub/"
Public ReadOnly Property MyPage As String
Get
Return _subDirectory + "mypage.aspx"
End Get
End Property
End Module
End Module
I want to declare it like this on a page Response.Redirect(PageDirectory.Sub.MyPage)
but i can't seem to get a module inside a module. My assumption was that a module is the equivalent to a c# static.
Module already says that everything in the class is static, that's why you can't have modules inside of modules.
If you want specific class member be static, you use "shared" on that class member.
https://msdn.microsoft.com/en-us/library/7825002w(v=vs.90).aspx
I think I've worked out the answer. But unsure if its the 'right' way to do this.
Public Module PageDirectory
Private _subDirectory As String = "/sub/"
Public Structure SubStruct
Public Shared ReadOnly Property MyPage As String
Get
Return _subDirectory + "mypage.aspx"
End Get
End Property
End Module
End Module
I created a simple solution with an EDMX file that possess one table Sport with 2 field IdSport and Label. I would like to insert a record in DB with an object inherited of the Sport object created by EF.
Public Class Index
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim aSport As New TestSport()
Using ctx As New FormationEntities
ctx.AddObject("Sport", aSport)
ctx.SaveChanges()
End Using
End Sub
End Class
Public Class TestSport
Inherits Sport
End Class
With an Sport object it work but not with TestSport. I need the inherited class for adding some properties and others functionnalities, but when I save it, I would like to save only the property possessed by the parent object Sport.
Error message:
Mapping and metadata information could not be found for EntityType
I know that the usual way is to use partial class but on my project, the EDMX file is in another project, so the only solution I see is to use an inherited class.
What am I doing wrong? How to fix my problem? Is it exist a better way to do it?
Thanks.
On searching through gooogle I found the following link, where a very similar scenario is discussed:
Deriving from classes generated by Entity Framework in C#
Although there is one post marked as answer, but the second answer is equally relevant.
Hope this helps.
Entity Framework appears to use a kind of reflection during the saving of your entities, and is probably why your inheritances do not work. One way you could still add functionality to your enties(albeit only functions) is using Extension methods: http://msdn.microsoft.com/en-us//library/bb383977.aspx
But if it is more than just some functions you need to add, consider a more structural solution. Having part of your object in a data layer and part of that same object in an upper layer is not a good separation of responsibilities.
Instead of having part of the class in your data project(I assume), and part of it in another project, consider creating one 'Logics class' in your project which wraps around your entity and adds functionality that way. You could for example do this by exposing the entity directly:
public class SportLogic
{
private Sport _sport;
public Sport Sport { get { return _sport; } }
public string SomeNewProperty { get; set; }
public void DoStuff() {};
}
Or the way I use where the logics object is acting as an actual logical wrapper around the entity. It is cleaner because it obfuscates the entity entirely: any calling code wil not need knowledge of your entity(Sport) object.
public class SportLogic
{
private Sport _sport;
public string SportProperty { get { return _sport.SportProperty; } set { _sport.SportProperty = value; } }
public string SomeNewProperty { get; set; }
public void DoStuff() {};
}
I'm building a first MVC app in ASP.NET and I'm using link2SQL model to work with data.
All tutorials on the microsoft site let you write LINQ code in the controller to get data and pass it to the view, like this:
Function Index() As ActionResult
Dim datacontext As New ErrorVaultDataContext
Dim questions = From q In datacontext.Questions
Where q.fk_status_id = 1
Order By q.date Descending
Select q
Return View(questions)
End Function
That works, but it's confusing me on where to place my business logic. I would like to implement business logic like "can this user get this data?" in this simple example.
Does anyone know how this works in conjunction with linq 2 SQL?
This LINQ query is the business logic. The problem is that in this example it is hardcoded in the controller thus making it tied to the database.
You could abstract it into an interface which will perform this query so that your controller is no longer dependent on a datacontext. Then you could have an implementation of this interface which will perform the actual data access:
Public Interface IBusinessRepository
Function GetQuestions(statusId As Integer) As IEnumerable(Of Question)
End Interface
Public Class BusinessRepositorySql
Implements IBusinessRepository
Public Function GetQuestions(statusId As Integer) As IEnumerable(Of Question) Implements IBusinessRepository.GetQuestions
' TODO: Perform the data access here
Throw New NotImplementedException()
End Function
End Class
Then the controller could use the business logic (In this case all it needs is to get questions filtered by some condition):
Public Class HomeController
Inherits Controller
Private ReadOnly _repository As IBusinessRepository
Public Sub New(repository As IBusinessRepository)
_repository = repository
End Sub
Public Function Index() As ActionResult
Dim questions = _repository.GetQuestions(1)
Return View(questions)
End Function
End Class
Then you could build a custom controller factory that will inject the proper implementation in the controller.
you need to look at patterns beyond MVC for instance the Repository pattern may be a good place to put the LIN2SQL then build a BLL (Business Logic Layer) between that and your controllers to do the business logic
I agree with Pharabus, regardless of which presentation layer you're using (webforms vs. mvc) you probably want to encapsulate your business logic in its own layer. That way your controller actions would make calls to the service/business layer objects instead of making use of the ORM (EF/linq2sql) context directly.
I have been sharing database variables using the following code:
Namespace DataAccessVariables
Public Class Vars
Public Shared s As String
Public Shared con As String = WebConfigurationManager.ConnectionStrings("Dev").ToString()
Public Shared c As New SqlConnection(con)
Public Shared x As New SqlCommand(s, c)
End Class
End Namespace
I then import this to my project like this:
Imports DataAccessVariables.Vars
When I check the site with FXCop, I get this message:
Error, Certainty 90, for StaticHolderTypesShouldNotHaveConstructors
{
Target : DBVars (IntrospectionTargetType)
Resolution : "Remove the public constructors from 'Vars'."
Help : http://msdn2.microsoft.com/library/ms182169(VS.90).aspx (String)
Category : Microsoft.Design (String)
CheckId : CA1053 (String)
RuleFile : Design Rules (String)
Info : "Instances of types that define only static members
do not need to be created. Many compilers will automatically
add a public default constructor if no constructor
is specified. To prevent this, adding an empty private
constructor may be required."
Created : 2010/04/20 01:25:16 PM (DateTime)
LastSeen : 2010/04/21 07:17:46 AM (DateTime)
Status : Active (MessageStatus)
Fix Category : Breaking (FixCategories)
}
If I remove the 'Public Shared' from the declarations, then the variables are not picked up in my pages. Can anyone show me the correct way of sharing them?
Thanks a lot,
Phil.
This error isn't telling you to remove the Public Shared variables. Instead it's letting you know that it is possible to create a new instance of your Vars class, even though it includes only Shared members. To resolve the issue, define a private constructor:
Private Sub New()
End Sub
This will prevent any code creating an instance of the Vars class outside of the class itself.
Is that the only code in your class?
Also, you should not create a global (static) SqlConnection. Simply create the SqlConnection and SqlCommand objects on-demand. Connection pooling will ensure that only one physical database connection is made at a time.
The way you've got it here, it's not thread-safe (if two people make a request at the same time, for example, things are going to get really screwy).
am trying to implement fluent nhibernate in MVC project...there were no build errors... but when i run the project i get this exception
System.Xml.Schema.XmlSchemaValidationException: The element 'class' in namespace 'urn:nhibernate-mapping-2.2' has incomplete content. List of possible elements expected: 'meta, subselect, cache, synchronize, comment, tuplizer, id, composite-id' in namespace 'urn:nhibernate-mapping-2.2'.
have no idea what am doing wrong here... the following is the code for opening session factory...
Private Function CreateSessionFactory() As ISessionFactory
Dim sessionFactoryObject As ISessionFactory
sessionFactoryObject = Fluently.Configure().Database(FluentNHibernate.Cfg.Db.MsSqlConfiguration.MsSql2005.ConnectionString("Data Source=.\sqlexpress;Initial Catalog=Designs;User ID=sa;Password=root")).Mappings(Function(x) x.FluentMappings.Add(GetType(DesignMap))).BuildSessionFactory()
Return sessionFactoryObject
End Function
this is really driving me nuts....thanks in advance...:)
update-the mappings
the design table map
Public Class DesignMap
Inherits ClassMap(Of Design)
Public Sub DesignMap()
Table("DesignList")
Id(Function(x) x.DesignId)
Map(Function(x) x.DesignType)
References(Function(x) x.Designer, "DesignerId")
End Sub
End Class
the designer table map
Public Class DesignerMap
Inherits ClassMap(Of Designer)
Public Sub DesignerMap()
Table("DesignerList")
Id(Function(x) x.DesignerId)
Map(Function(x) x.DesignerName)
Map(Function(x) x.DesignerCompany)
HasMany(Function(x) x.DesignersDesigns)
End Sub
End Class
new edit-- the entity property looks like this
Public Overridable Property Name() As String
Get
Return _name
End Get
Protected Set(ByVal value As String)
_name = value
End Set
End Property
am i going the right way..?
I'm not quite sure as the mappings seem ok. I can see one error tough, you have only mapped one of your classes:
.Mappings(Function(x) x.FluentMappings.Add(GetType(DesignMap)))
That should not cause this type of error tough. If you add both your mappings and call the method .ExportTo(#"C:\your\export\path") you will get the actual xml mappings. This way it's easier to see the error. You can do that like this:
.Mappings(Function(x) x.FluentMappings.Add(GetType(DesignMap)).Add(GetType(DesignerMap
).ExportTo(#"C:\your\export\path"))
You can also use the method AddFromAssemblyOf (or some other. There is a few choices) if you don't want to add the mappings one by one.
Try exporting the mappings and see if you can find any error. Or you can post the xml mappings and someone else might find something.
There are several things that can cause this. When using automappings, you will get this if you incorrectly specify the assemblies and namespaces to look in. Other things (more likely in your case) that could cause it, are entity properties that aren't marked as public virtual, having an entity constructor with arguments, but neglecting to make a default constructor, or inheriting your entities from a base class.
I would probably first check to make sure all of your entity properties are "public virtual".
found the problem...the constructor for the map was wrong...it should be like this...
Public Class DesignMap
Inherits ClassMap(Of Design)
Public Sub New()
Table("DesignList")
Id(Function(x) x.DesignId)
Map(Function(x) x.DesignType)
References(Function(x) x.Designer, "DesignerId")
End Sub
End Class
problems of working in both C# and vb.net at the same time i guess..!!
and "Matthew Talbert" was correct...making all the properties Overrideable is important..
thanks guys...:)