Entity Framework not retrieving values when used in WCF service - c#

I have this action method in MVC which retrieves data from table using a DbContext:
public ActionResult Index()
{
TwitterContext context = new TwitterContext();
List<TwitterUser> Users = context.User.ToList();
return View(Users);
}
It retrieves the values as expected:
But when I use the same code as a service, it retrieves nothing:
I am calling the service method from the client like this
public class TwitterController : Controller
{
// GET: Twitter
public ActionResult Index()
{
TwitterServiceReference.TwitterContractClient client = new TwitterServiceReference.TwitterContractClient("BasicHttpBinding_ITwitterContract");
List<TwitterServiceReference.TwitterUser> user = client.User().ToList();
return View(user);
}
}
I am using the same connection strings in both cases
<add name="TwitterContext"
connectionString="Integrated Security=true;initial Catalog=TwitterDatabase;server=MYNAME-PC\SQLEXPRESS"
providerName="System.Data.SqlClient"/>
I have all the data filled in the table:
Why is the data empty? How to solve this?
UPDATE:
After checking the SQL Server i see that a database is generated with the name
"TwitterService.TwitterContext , the database is autogenerated when i run the app, and the autogenerated tables data is empty, that is why i am getting empty data returned.

i think you forgot to copy your web.config connection string to that app.config.This might be the issue.
Edit:
i mean the project in which your DataContext class resides

The TwitterUser type you are using in MVC is in namespace Twitter.Models but the one you are using in WCF is in namespace TwitterServiceReference. Therefore, EF will treat them like different things. Your TwitterContext is also in different namespaces and as a consequence this is what is happening (from your comment):
I Just checked the SQL Server Management studio, i think the code created database named "TwitterService.TwitterContext" don't know how and with the same tables as DbContext class
And since it is a brand new database, it has no data and therefore in the WCF service you are not getting any records.
You can have different contexts and use the same database by specifying the same connection string as shown below:
public class TwitterContext : DbContext
{
public MovieDBContext()
: base("TwitterContext")
{
}
}
A Better Approach
Create a separate project and put all your DbContext related code in that project. Most people will refer to this as the Data Access Layer. Then use that project in both the MVC application and the WCF services. This way you will share the TwitterUser and other types in both, and possibly more, applications. You may use Repository Pattern to implement this layer.
But what if my MVC application needs additional info?
There will be cases where TwitterUser may not be sufficient for your MVC views and you may need additional properties. In that case, you can create a Model specifically for that view (some people call this view model but I stay away from that since that is a term used in MVVM and it is very different). The class can be designed like this:
public class TwitterUserModel
{
public TwitterUserModel(TwitterUser user)
{
this.TwitterUser = user;
}
public string AnotherPropertyNeededByView {get; set;}
public TwitterUser TwitterUser { get; set; }
}
Or you can use AutoMapper or similar mappers to map from TwitterUser to TwitterUserModel.

After some trials i got the success
i just added this code
public class TwitterContext : DbContext
{
//Added this Code with the connection string
public TwitterContext() : base(#"Integrated Security=true;server=MYNAME-PC\SQLEXPRESS;database=TwitterDatabase")
{
//Disable initializer
Database.SetInitializer<TwitterContext>(null);
}
public DbSet<TwitterUser> User { get; set; }
public DbSet<TwitterUserData> UserData { get; set; }
}
I first tried adding "TwitterContext" as base("TwitterContext") which is the name of my connection string and matches with my DbContext class name which did not work, so i directly added the connection string, the data is retrieved now and is preventing from generating new database.

Related

MVC .net core: Validator.TryValidateObject is not validating attributes, defined in a buddy class

We used DB-first approach to generate models in a .NET core application. DataAnnotations were put in a "buddy" metadata class so as to avoid writing in an autogenerated file. When controller calls TryValidateModel, all works well, Name property is required.
public partial class User
{
public string Name { get; set; }
}
[ModelMetadataType(typeof(UserMetaData))]
public partial class User : IValidatableObject
{
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) { }
}
public class UserMetaData
{
[Required]
public string Name { get; set; }
}
On a service layer of the app, we want to implement additional validation, that also checks if objects are valid in regards to data annotations. This is done via
Validator.TryValidateObject()
which successfully calls Validate method, but disregards data annotations - user is valid, even with an empty name.
TL;DR:
MVC (web project) knows how to consider data annotations put in a "buddy" class via ModelMetadataType attribute, service layer project does not.
I thought i have found the answer here, but it seems that
TypeDescriptor.AddProviderTransparent
does not work for .net core apps.
Any ideas would be greatly appreciated.
I really hoped for a one line solution :)
I abused ashrafs answer to his own question like so:
var metadataAttr = typeof(T).GetCustomAttributes(typeof(ModelMetadataTypeAttribute), true).OfType<ModelMetadataTypeAttribute>().FirstOrDefault();
if (metadataAttr != null)
{
var metadataClassProperties = TypeDescriptor.GetProperties(metadataAttr.MetadataType).Cast<PropertyDescriptor>();
var modelClassProperties = TypeDescriptor.GetProperties(typeof(T)).Cast<PropertyDescriptor>();
var errs =
from metaProp in metadataClassProperties
join modelProp in modelClassProperties
on metaProp.Name equals modelProp.Name
from attribute in metaProp.Attributes.OfType<ValidationAttribute>()
where !attribute.IsValid(modelProp.GetValue(model))
select new ValidationResult(attribute.FormatErrorMessage(Reflector.GetPropertyDisplayName<T>(metaProp.Name)), new[] { metaProp.Name });
validationResults.AddRange(errs);
}

c# filter database results using EF similar to SQL WHERE Clause

I've connected to my database using Entity Framework and am building my first MVC app for use in a web page.
I can get the controller to populate public strings in my models with no problem... the issue I'm having is that I can't figure out how to filter responses from my database.
I expect to have only one item returned which I will display in the view with #Model.BusinessUnit
Here's my Model Class for the database table:
public partial class TBL_Wholesale_UWS_BusinessUnits
{
public int PrimaryID { get; set; }
public string BusinessUnit { get; set; }
public string Status { get; set; }
}
Here's what I have in my controller:
public ActionResult test(int PrimaryID)
{
var testing = new TBL_Wholesale_UWS_BusinessUnits();
// maybe putting new is the wrong thing to do as that would be wiping the class? IDK
return View(testing);
}
As you can see, the PrimaryID is passed to the controller via the querystring and this is recognised without issue, but I'm at a loss as to where to add the filter, I assumed it would be something like...
var testing = TBL_Wholesale_UWS_BusinessUnits.Where(TBL_Wholesale_UWS_BusinessUnits.PrimaryID = PrimaryID);`
but Visual Studio is telling me in no uncertain terms that this this wrong.
Had this been classic asp I would have just made a record set and used the where clause in SQL, but as this is built with the Entity Framework to do my connecting I don't really know where to start.
Any help would be greatly appreciated.
If you are only trying to return that one specific object to the view.. then you need to find that int PrimaryID in the database and retrieve that specific record.
What you are doing is simply creating a new instance of the TBL_Wholesale_UWS_BusinessUnits class which is empty.
Try this:
public ActionResult test(int PrimaryID)
{
var testing = db.TableName.Find(PrimaryID);
// db = Whatever the variable holding your connection string is.. maybe DbContext
// TableName = Whatever table in your database that holds the record you want
// This will return the specific object that you are looking for
return View(testing);
}
I hope this helps!

MVVM View Model Collections with Web API, View Model and Entity Framework

question about collection helper classes for view models with in a Web API <> View Models <> Entity Framework <> Database structure.
I'm trying to get a design started on a project which will use an "API" front end to get data, then HTML/Javascript pages to get and render.
In trying to create an MVVM approach to this I am not sure if what I want to implment is a good approch or not.
And that is a get Collection methods for the ViewModels. The user on the HTML side, will only be able to edit one Object at a time, so the collection is only to provide arrays/listing of the objects, making the Web API classes "less cluttered".
Using the Visual Studio MVC/Web API porject / c# (Visual Studio 2013 so MVC 5 components)
so using example of a Chair object
NOTE: in actual code would not do "new MyEntity().Chairs." all the time, it would be set as a variable with in the class. Simply written example long hand to make clear.
Web API part:
we will pluralize api objects front point
Web API controller = ChairsController
With 2 gets
namespace FurnitureAPI.Controllers
{
[Authorize]
public class ChairsController : ApiController
{
// GET api/chairs
public IHttpActionResult Get()
{
var chairs = ViewModels.Chairs.Get();
return Ok(chairs);
}
// GET api/chairs/5
//public string Get(int id)
public IHttpActionResult Get(int id)
{
var chair = ViewModels.Chairs.Get(id);
return Ok(chair);
}
public ... GET() {...} //all chairs
public ... GET(int id) {} //single chair where id
In the database side, we have Chair table. This will be singular for database.
Database already exists, so using Entity Framework and database first modelling we get in Entities
var furniture_db = new Models.FurnintureEntities();
and
Models.Chair
So in the middle want a View Model Chair.
namespace FurnitureAPI.ViewModels {
public class Chair {
public int ChairID { get; set; }
public string Name { get; set; }
public Chair() { }
public Chair(int chairid, string name) {
ChairID = chairid;
Name = name;
}
public Chair(Models.Chair db_chair) {
ChairID = db_chair.ChairID;
Name = db_chair.Name;
}
}
In my thinking, the Web API ChairsController I do not want to have any entity framework code.
but I want api to call something to get a List/Collection of Chair view models
So Im thinking, add Chairs as a class in the ViewModel namespace, which will be static.
so web api becomes
public IHttpActionResult Get()
{
var chairs = ViewModels.Chairs.Get();
return Ok(chairs);
}
and the View Model Collection Chairs then looks like
namespace FurnitureAPI.ViewModels {
public static class Chairs {
public static List<Chair> Get() {
List<Chair> chairs = (from s in new Models.FurnintureEntities().Chairs
select new ViewModel.Chair {
ChairID = s.ChairID,
Name = s.Name
}).ToList();
return chairs;
}
public static Chairs Get(int id) {
var chair = new FurnitureEntities().Chairs.SingleOrDefault(c => c.ChairID == id);
return chair != null ? new ViewModel.Chair(chair) : null;
}
}
So the question, is this Chairs collection wrapper okay/ideal/bad/run for the hills/other, or is there a different approach someone could point to?
I do not understand why struggling to find reference to on the internet, sure hope its not grumpy old age kicking in.
I find lots of WPF MVVM Entity Framework database first stuff, but I just want to make 'simple' Web API to expose the database to make HTML views with.
Maybe I do not need to bother with the View Model and simply serialize the Entity in the Web API methods?
Thanks.
Unfortunately I've been struggling with this too and it seems this subject doesn't get the love it should have.
Anyway, among the tools there are, you can count:
Breeze# (MIT)
TrackableEntitities (MIT)

How to make grid operations work with custom property in EF?

In a ASP.NET MVC 5 web site I have a GridView using the devexpress component binding using the LINQ method.
EF generated a partial class to map a table that i use to display in that gridview.
In this partial class generated by the EF i have a ID_Status property wich has a corresponding description in other table. I made another partial class to deal with this custom Property and it works ok, except when i try to make a 'Sort' operation clicking on the header of this column.
The partial class generated by the EF.
[Table("Test")]
public partial class Test
{
[Key]
public long ID_Test { get; set; }
public long ID_TestStatus { get; set; }
//other properties
}
My Custom partial class:
public partial class Test
{
private static readonly TestRepository _testRepository;
static TestRepository()
{
_testRepository= new TestRepository();
}
public string StatusDescription
{
get { return _testRepository.GetStatusDescriptionById(ID_TestStatus); }
}
}
When i try to Sort using another column it works fine, but when i try to Sort using the custom property Column all the grid cell values gets empty, without any value.
Any suggestion?
It's not a very good idea to have data access code inside an entity. One reason is that it makes it very hard to write unit test. Another reason is that it is very likely to give rise to the n + 1 anti pattern. In your case, it does: one (1) query to get the Tests, then each Test (n) sends a separate query to the database to get its StatusDescription.
The way you implemented it also raises some eyebrows, because
_testRepository is static, which meas there is probable some context instance living for the entire lifecycle of the application - unless GetStatusDescriptionById creates a new context for each call, but that wouldn't be a good idea either.
The GetStatusDescriptionById call is made each time the property is accessed. In a web application this may not be a big problem because the objects are newly created each time they are requested anyway, but in other environments this could be highly inefficient.
A better approach would be to fetch the Testss with their Status included:
context.Tests.Include(t => t.TestStatus)
and have an unmapped property like
public string StatusDescription
{
get { return TestStatus== null ? string.Empty : TestStatus.Description; }
}
better still (in my opinion) would be not to show Test objects directly, but TestDto objects like
public class TestDto
{
public string StatusDescription { get; set; }
//other properties that match Test's properties
}
and use a tool like AutoMapper to map a collection of Tests to TestDtos. If Test has a property Status and TestStatus has a property Description, AutoMapper will be able to flatten that into StatusDescription automatically.
Both this StatusDescription property and the Dto appraoch set the state of a Test(Dto) object once. I don't think any grid component can mess with that.

When should I write code in the controller vs. model?

Without a doubt I know what the controllers and models are used for. However, I am able to write code that interacts with my db, for example adding users to a table, on either the controller or model. At what times should I write code in the controller vs. in model? Even though both work, what would be a more organized or practical way. Could you please post examples if the answer is ambiguous?Thx
For that, you should add a logic layer or logic classes. The controller should determine wants to do and can do, shuffle them in the right direction (logic layer), then determine what to show the user after the logic. Putting the logic in a separate layer will help keep your controllers lean and promote code reuse.
In the domain core, we only have models with properties. All logic is performed in a different layer, except for things like a property that returns fields concatenated in a format.
Code to access the database should be in service layer instead of keeping in Controller or Model.
Accessing Database Entities from Controller
Here is my answer for the above question, you can also read others answers why you should keep in separate layer.
namespace MyProject.Web.Controllers
{
public class MyController : Controller
{
private readonly IKittenService _kittenService ;
public MyController(IKittenService kittenService)
{
_kittenService = kittenService;
}
public ActionResult Kittens()
{
// var result = _kittenService.GetLatestKittens(10);
// Return something.
}
}
}
namespace MyProject.Domain.Kittens
{
public class Kitten
{
public string Name {get; set; }
public string Url {get; set; }
}
}
namespace MyProject.Services.KittenService
{
public interface IKittenService
{
IEnumerable<Kitten> GetLatestKittens(int fluffinessIndex=10);
}
}
namespace MyProject.Services.KittenService
{
public class KittenService : IKittenService
{
public IEnumerable<Kitten> GetLatestKittens(int fluffinessIndex=10)
{
using(var db = new KittenEntities())
{
return db.Kittens // this explicit query is here
.Where(kitten=>kitten.fluffiness > 10)
.Select(kitten=>new {
Name=kitten.name,
Url=kitten.imageUrl
}).Take(10);
}
}
}
}
ASP.NET MVC and MVC, in general, is a presentation layer pattern; thus your interaction with the database should be in a layer beyond the presentation layer, usually a data-access layer, but it could be a service layer or business layer as well.

Categories