I working to code first technique with EF4.1, WCF webservice, and Sql azure. To improve the performance i wanted to create the View to fetch data at server side. but according to this
we can not use sql View with EF code first.
Because the database and models are defined. it has the data. to re create and dump data for the only creating view is time taking process.
so i just created the View explicitly at sql server.
now I want to call that view from my wfc web service. Now i want to access that view as dataset in WCF. need guidlines. and right approach
Could you define a table in codefirst with the same columns, then create a custom initializer that drops the table from the database and creates it again as a view?
Then you should be able to query it just like normal.
Edit Update to show working example
public class User
{
public int Id { get; set; }
public string Email { get; set; }
}
public class UserView
{
public int Id { get; set; }
public string Email {get; set;}
}
public class TestContext : DbContext
{
static TestContext()
{
Database.SetInitializer<TestContext>(new DatabaseInitializer());
}
public DbSet<User> Users { get; set; }
public DbSet<UserView> UserView { get; set; }
}
class DatabaseInitializer : DropCreateDatabaseIfModelChanges<TestContext>
{
protected override void Seed(TestContext context)
{
base.InitializeDatabase(context);
context.Database.ExecuteSqlCommand("drop table UserViews");
context.Database.ExecuteSqlCommand(#"CREATE VIEW [dbo].[UserViews] AS SELECT *
from [dbo].[Users]
GO");
context.Users.Add(new User() { Email = "test#test.com" });
}
}
...
using (TestContext context = new TestContext())
{
context.UserView.ToList(); //contains all the users
}
Related
I am building a Web API and have two models: Task and Feature:
public class Feature
{
[Key]
public long FeatureId { get; set; }
public string Analyst_comment { get; set; }
public virtual ICollection<User_Task> Tasks { get; set; }
public Feature()
{
}
}
public class User_Task
{
[Key]
public long TaskId { get; set; }
public string What { get; set; }
[ForeignKey("FeatureId")]
public long? FeatureId { get; set; }
public User_Task()
{
}
}
I create Tasks first and then create a Feature that combines few of them. Task creation is successful, however while creating a Feature with existing Tasks, my controller throws an error saying the task already exists:
My FeatureController has following method:
//Create
[HttpPost]
public IActionResult Create([FromBody] Feature item)
{
if (item == null)
{
return BadRequest();
}
** It basically expects that I am creating a Feature with brand new tasks, so I guess I will need some logic here to tell EF Core that incoming tasks with this feature already exist **
_featureRepository.Add(item);
return CreatedAtRoute("GetFeature", new { id = item.FeatureId }, item);
}
How to tell EF core that incoming Feature has Tasks that already exist and it just needs to update the references instead of creating new ones?
My context:
public class WebAPIDataContext : DbContext
{
public WebAPIDataContext(DbContextOptions<WebAPIDataContext> options)
: base(options)
{
}
public DbSet<User_Task> User_Tasks { get; set; }
public DbSet<Feature> Features { get; set; }
}
And repo:
public void Add(Feature item)
{
_context.Features.Add(item);
_context.SaveChanges();
}
When calling Add on a DBSet with a model that was not loaded from EF, it thinks it is untracked and will always assume it is new.
Instead, you need to load the existing record from the dbcontext and map the properties from the data passed into the API to the existing record. Typically that is a manual map from parameter object to domain. Then if you return an object back, you would map that new domain object to a DTO. You can use services like AutoMapper to map the domain to a DTO. When you're done mapping, you only need to call SaveChanges.
Generally speaking, loading the record and mapping the fields is a good thing for the security of your API. You wouldn't want to assume that the passed in data is pristine and honest. When you give the calling code access to all the properties of the entity, you may not be expecting them to change all the fields, and some of those fields could be sensitive.
I am trying to create a SPA model which is able to create, update, delete scheduled tasks in Visual Studio 2012 using MVC4 Hottowel SPA template. Here i have a demo class which I need to use in creating database but unable to get 1) the context of the database.
2) how to configure the database in this project. I tried with creating connection using (LocalDb)\v11.0 sql server but its showing error that entity framework 6 or above is not supported with this application.
public class JobDemo
{
public string JobName { get; set; }
public string JobDescription { get; set; }
public string Frequency { get; set; }
public bool JobStatus { get; set; }
public bool JobIsActive { get; set; }
public DateTime LastModifiedOn { get; set; }
}
This is my class which I wanna use to create database of scheduled tasks/jobs and then query on them
public class DemoDb : DbContext
{
public DbSet<JobDemo> Jobject { get; set; }
public DemoDb() : base("name=DefaultConnection")
{
}
}
The class is creating the DbContext of my JobDemo Class. But after that i am unable to create database connection which use my class and use the following attributes defined in my JobDemo class.
Even though the EF6 is not supported in SPA template, the SqlServer or SqlServerCompact Database can be used with HotTowel SPA template as they support the model and can be used with Breeze Api or Simple controllers with get and post methods can be used to retrieve and store data.
I keep getting error when I try to access a model from an edit or details action.
The model backing the 'InjuriesContext' context has changed since the
database was created. Consider using Code First Migrations to update
the database (http://go.microsoft.com/fwlink/?LinkId=238269).
First I tried adding a migration even though I was sure I hadn't changed anything. Still recieved the same error after an update-database.
Then I removed all the migrations and the database and started a clean database with an inital migration and update. Same error. Nothing was changed.
Model is:
public class InjuriesContext : DbContext
{
public InjuriesContext()
: base("DBCon")
{
}
public DbSet<Patient> Patients { get; set; }
public DbSet<Injury> Injuries { get; set; }
}
public class Injury
{
public int Id { get; set; }
public string Type { get; set; }
public int PatientId { get; set; }
}
Here is controller --
public ActionResult Edit(int id = 0)
{
Injury injury = db.Injuries.Find(id);
if (injury == null)
{
return HttpNotFound();
}
return View(injury);
}
It errors on the injuries.find. I do not have any injuries entered so I expect it to return a 404 like my other controllers but it doesn't like something about this. The only difference between this and my other models is the y to ies for plural. Does Entity Framework not handle this?
There should not be any plural restriction, as you defined everything clearly in your classes anyway.
Have you created the Injuries table?
I belive the table Injury will get created automatically. the variable injury might be a bit close, but I have to test this myself.
Rather try:
public class Injury
{
[Key]
public int Id { get; set; }
[Required]
public string Type { get; set; }
[Required]
public int PatientId { get; set; }
}
private InjuriesContext db = new InjuriesContext();
Injury objInjury = db.Injuries.Find(id);
if (objInjury == null)
{
return HttpNotFound();
}
return View(objInjury);
Hope this helps
It turns out my issue was with multiple contexts. I thought you had to create a separate context for each model class. Apparently Entity Framework needs one context. I went through and created a class for my context and put all my DBsets in that class.
public class ProjContexts : DbContext
{
public ProjContexts()
: base("ProjDBCon")
{
}
public DbSet<Patient> Patients { get; set; }
public DbSet<PreHosp> PreHosps { get; set; }
public DbSet<UserProfile> UserProfiles { get; set; }
public DbSet<Injury> Injuries { get; set; }
}
}
Then I removed all the migrations as per this post and enabled the migrations again did an add migration and update then I got the expected result.
Bottom Line--- Don't have multiple context classes in your project. Not sure if this is possible but after changing the above everything is working as expected. Not sure why it was working when I had two separate contexts and added the third? Maybe because they had foreign keys with one another?
I'm currently working on and ASP.NET MVC application in which I have a User entity like follows:
public class User
{
public virtual int Id { get; protected set; }
public virtual string Name { get; protected set; }
public virtual string Role { get; protected set; }
public virtual Location Location { get; protected set; }
}
Where location is just as straightforward:
public class Location
{
public virtual string Id { get; protected set; }
public virtual string Building { get; protected set; }
public virtual string City { get; protected set; }
public virtual string Region { get; protected set; }
}
My complication arises because I want to populate the User from Active Directory and not the database. Additionally, several classes persisted to the database reference a user as a property. I've got an ADUserRepository for retrieval, but I don't know how to integrate these Users into my object graph when the rest is managed by NHibernate.
Is there a way for NHibernate to persist just an id for a User without it being a foreign key to a Users table? Can I map it as a component to accomplish this? I've also looked at implementing IUserType to make the translation. That way it would map to a simple field and ADUserRepository could be put in the chain to resolve the stored Id. Or am I trying to hack something that's not really feasible? This is my first time around with NHibernate so I appreciate any insight or solutions you can give. Thanks.
Update
It appears my best solution on this will be to map the User with an IUserType and inject (preferably with StructureMap) a service for populating the object before its returned. Framed in that light there are a couple of questions here that deal with the topic mostly suggesting the need for a custom ByteCodeProvider. Will I still need to do this in order for IUserType to take a parameterized constructor or do the comments here: NHibernate.ByteCode.LinFu.dll For NHibernate 3.2 make a difference?
using a Usertype to convert user to id and back
public class SomeClass
{
public virtual string Id { get; protected set; }
public virtual User User { get; protected set; }
}
// in FluentMapping (you have to translate if you want to use mapping by code)
public SomeClassMap()
{
Map(x => x.User).Column("user_id").CustomType<UserType>();
}
public class UserType : IUserType
{
void NullSafeSet(...)
{
NHibernateUtil.Int32.NullSafeSet(cmd, ((User)value).Id, index);
}
void NullSafeGet(...)
{
int id = (int)NHibernateUtil.Int32.NullSafeGet(cmd, ((User)value).Id, index);
var userrepository = GetItFromSomeWhere();
return userrepository.FindById(id);
}
}
I am using MVC3 and Entity Framework. I have a class called User with 20 different properties. I have already created a database and filled it with some data. I want to break out the Addresses property and make it it's own class.
namespace NameSpace.Domain.Entities
{
public class User
{
public int UserId { get; set; }
...
...
public string AddressOne { get; set; }
public string AddressTwo { get; set; }
}
}
I want to break out both Addresses like so
namespace NameSpace.Domain.Entities
{
public class User
{
public int UserId { get; set; }
...
...
public Addresses Addresses { get; set; }
}
public class Addresses
{
public string AddressOne { get; set; }
public string AddressTwo { get; set; }
}
}
HERE'S MY QUESTION:
Since I already have the data table filled with data, how can I update this in the Server Explorer?
Thanks ( if you need more info please let me know )
If you are using EF code first 4.3 you can use the concept of migrations to achive what you want.
You will need to do a code based manual migration since you change is a bit to advanced for the framework to figure it out itselfe.
Further reading: http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-code-based-migrations-walkthrough.aspx