Lambda Expression - Error Cannot implicitly convert type `vicoapi.Pictures' to `System.Collections.Generic.List<vicoapi.Pictures>' (CS0029) - mysql

Hello Together following my Code:
public class SampleData : DropCreateDatabaseIfModelChanges<VicoTvEntities>
{
protected override void Seed(VicoTvEntities context)
{
var pictures = new List<Pictures>{
new Pictures { Name = "Testbild", Url="localhost/test" }
};
var user = new List<User>{
new User{Username="Muster", Password="Pass",Email="max.muster#mustermail.com",Bio="Musterbiografie", Pictures = pictures.Find(pic => pic.Name == "Testbild")}
};
}
}
}
I try to build an API and at the moment, I work on the connection of the DB to the code. I'm following this tutorial: https://www.asp.net/mvc/overview/older-versions/mvc-music-store/mvc-music-store-part-4
My Problem is, whenever I try to add the Picture it won't work, because of this converting error. How can I avoid this problem and implement the picture to the User.
My Source Tree looks like this:
Source Tree
The User Class looks as following:
public class User
{
public int IdUser { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Email { get; set; }
public string Bio { get; set; }
public List<Pictures> Pictures { get; set; }
public List<Follow> Following { get; set; }
public List<Follow> Followed { get; set; }
}
The Error I get looks like this:
/Users/username/vicotv-Backend/vicoapi/vicoapi/Models/SampleData.cs(126,126): Error CS0029: Cannot implicitly convert type `vicoapi.Pictures'to System.Collections.Generic.List' (CS0029) (vicoapi)

Although you don't show the class here, I'm fairly certain that your User class has a property defined something like this:
public List<Pictures> Pictures { get; set; }
If that is the case, you need to assign the property to the whole list like this:
user.Pictures = pictures
If you want a user to only be able to have one picture then you need to define the Picture property on the User class like this:
public Pictures Picture { get; set; }
If you define the Picture property like this it should work with your current code.
P.S. I would definitely recommend renaming your "Pictures" class to "Picture". In general you should use the singular form for class names. Have a look at this page for more information.

Related

Return a non-mapped Entity property based on a SUM of child records in the EntityFramework

Using an example, I have the following two Entities. The OrderEntity contains a collection of OrderLineEntites
public class OrderEntity
{
public string Reference { get; set; }
public string Description { get; set; }
public bool Confirmed { get; set; }
[NotMapped]
public int OrderLineCount { get; set; }
[InverseProperty("Order")]
public virtual ICollection<OrderLineEntity> OrderLineEntity__OrderEntity { get; set; }
}
public class OrderLineEntity
{
public string Name { get; set; }
public string Description { get; set; }
}
Using the following code I can load all the OrderLineEntities for all confirmed orders.
DbSet<OrderEntity> orderEntity.Where(x => x.Confirmed).Include(x => x.OrderLineEntity__OrderEntity)
What I need to do is set the non-mapped OrderLineCount property with the Count of the OrderLine records (to save actually loading them).
So for each loaded Order I have a fully populated Entity including the [NotMapped] property with an empty OrderLine collection.
Advise would be appreciated :)
Thanks
You can do this, but you have to change your approach. You have to manually map the objects yourself:
var query = from a in context.Orders.Where(x => x.Confirmed)
select new OrderEntity
{
Reference = a.Reference,
Description = a.Description,
Confirmed = a.Confirmed,
OrderLineCount = a.OrderLineEntity__OrderEntity.Count
};
return query.ToList();

Return self referencing model in JSON format using Web Api 2 controller

I have a self referencing model called Folder and also an Entity called Content which contains the Folder Entity.
public class Folder : BaseEntity
{
public int Id { get; set; }
public string Name { get; set; }
public int? ParentId { get; set; }
public virtual Folder Parent { get; set; }
public virtual ICollection<Folder> Children { get; set; }
}
public class Content : BaseEntity
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public string HTML { get; set; }
public string Summary { get; set; }
public int XmlConfigId { get; set; }
public int FolderId { get; set; }
public virtual Folder Folder { get; set; }
}
Here is my Application Db context
public class ApplicationDbContext: DbContext
{
public DbSet<Folder> Folders { get; set; }
public DbSet<Content> Contents { get; set; }
public ApplicationDbContext() : base("ProjectDB") {
Database.SetInitializer<ApplicationDbContext>(null);
}
}
Everything works fine if i am using a razor view to display the data and also i am able to access the The Folder property that is inside the Content Entity.
The problem is when i try to display the data using Web API.
My web API
public class ContentApiController : ApiController
{
[HttpGet]
public IEnumerable<Content> GetAllContents()
{
return _unitofwork.Contents.GetAllContents();
}
}
On the Web API, the GetAllContents() function just returns the Entity models coming directly from the Folders DBSet. It is not calling the ToList() function since i want to do lazy loading. Here is the code for the GetAllContents() function.
public IEnumerable<Content> GetAllContents()
{
return ApplicationDbContext.Contents.Include(c=>c.Folder);
}
So in order for this to work i have to add.
Configuration.LazyLoadingEnabled = false;
to my applicationDbContext constructor which i really don't want.
and also
Global.asax
GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
WebApiConfig
JsonMediaTypeFormatter jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().Single();
jsonFormatter.UseDataContractJsonSerializer = false;
jsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
jsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
jsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.None;
Is there any way to expose the json data without out turning off Lazy loading. Thanks.
Just call ToList on your query, or, even better, ToListAsync:
[HttpGet]
public async Task<IEnumerable<Content>> GetAllContents()
{
return await _unitofwork.Contents.GetAllContents().ToListAsync;
}
Even if you enable LazyLoading, you cannot avoid to materialize your data before returning it to the client (and let the Serializer do its work).
In your MVC example, the framework itself enumerates the result in your View (I suppose), and thus you are not directly calling ToList, but in your scenario you have to materialize your Entities explicitly.
Please note that there is no performance issue in calling ToList/ToListAsync in your controller.

best way to exclude some parameters in a modelview when editing a page

I know there are a couple of options to exclude/include some parameters in a modelview like using bind or using interfaces. However I have some problems when I am trying to implement nested IEnumerable variables. For example:
public class TestViewModel()
{
public int Id { get; set; }
public IEnumerable<Organisation> KPI { get; set; }
}
public class Organisation
{
public string Id { get; set; }
public string Name {get; set;}
public DateTime StartDate {get; set;}
public IEnumerable<Regiod> CategoryValues { get; set; }
}
public class Region
{
public System.Guid Id { get; set; }
public System.Int32 RegionId { get; set; }
public int Value { get; set; }
public System.String RegionName { get; set; }
}
[HttpGet]
public ActionResult edit(int id)
{
var model = new TestViewModel();
// Do something to populate the model
view(model)
}
In the view page (razor) all fields are disabled or hidden, except field Value in Region class and StartDate in Organization. My action Code is something like:
[HttpPost]
public ActionResult edit(TestViewModel model)
{
// Do something to populate the model
}
Everything works fine, unless somebody uses for example fiddler to set other disabled or hidden values, so those fields will be updated.
What I am after is to update just enabled fields and exclude the rest even somebody tries to set a value for them.
I tried bind[Exclude and Include], but my problem is I can bind 2 values from different classes. I tried UpdateModel(model, include) and it didn't work.
Any advice would be appreciated.

Different login page for every client (on one server)

Scenario:
Currently, we have a website tool in asp.net MVC (www.tool.com/login).
Now, the client is looking into customizing the login page for several customers and they will have their own domain (but only one server for all).
for example:
www.client1.com/login,
www.client2.com/login,
www.client3.com/login
Yell at me if this is a stupid question.
But please help and give me an idea on how to implement it.
Should I create different login htmls for each client?
Related to my comment -
Create a Table with ClientInfo in DB:
Title
BackgroundColor
Language
URL --> This has to be unique for this to work [client1, client2]. Don't save the full URL -- Just the Host
Let's say you are passing a Model --> LoginModel to your LoginPage.cshtml
public class LoginModel
{
public string UserName { get; set; }
public string Password { get; set; }
public StyleDTO ClientStyles { get; set; }
}
public class StyleDTO
{
public string Title { get; set; }
public string LogoPath { get; set; }
public string BackGroundColor { get; set; }
}
In your controller when you load View:
public ActionResult Login()
{
var clientUrl = HttpContext.Current.Request.Url.Host;
var cs = dbContext.ClientInfo.First(s => s.Url == clientUrl);
var model = new LoginModel()
{
ClientStyles = new StyleDTO()
{
Title = cs.Title,
LogoPath = cs.LogoPath,
BackGroundColor = cs.BackGroundColor
}
};
}
then in your login View (LoginPage.cshtml):
#model LoginModel
<div style="background-color: #Model.BackGroundColor">
<h1>#Model.Title</h1>
</div>
create a config file with variables for client1, client2, client3
Keep same login page html and based on HTTP_referer pick one of the config variable and render the page based on that.

How to use properly the ChangeTracker.Entries<Entity> in Entity Framework Code First

this is my simple DbContext inheriting class:
public class School : DbContext
{
public DbSet<Activity> Activity { get; set; }
public DbSet<Student> Student { get; set; }
public override int SaveChanges()
{
string s = string.Empty;
foreach (var entry in ChangeTracker.Entries<Activity>().Where(a => a.State != EntityState.Unchanged))
s = entry.State.ToString();
foreach (var entry in ChangeTracker.Entries<Student>().Where(a => a.State != EntityState.Unchanged))
s = entry.State.ToString();
return base.SaveChanges();
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Configuration.ValidateOnSaveEnabled = false;
Configuration.LazyLoadingEnabled = true;
base.OnModelCreating(modelBuilder);
}
}
these are my entites:
public class Student
{
public int id { get; set; }
public string Name { get; set; }
public string Roll { get; set; }
//naviagtional property
public virtual IList<Activity> Activities { get; set; }
}
public class Activity
{
public int id { get; set; }
public double Maths { get; set; }
public double Science { get; set; }
public double History { get; set; }
//navigational property
public virtual Student Student { get; set; }
}
somewhere in my code i do this:
int studentId = Convert.ToInt32(Request.Form["Student.id"]);
Activity activity = dbContext.Activity.Where(e => e.Student.id == studentId).Single();
activity.Student.Name = Request.Form["Student.Name"];
activity.Student.Roll = Request.Form["Student.Roll"];
activity.Maths = Convert.ToDouble(Request.Form["Maths"]);
activity.Science = Convert.ToDouble(Request.Form["Science"]);
dbContext.SaveChanges();
Everything's normal and fine and works as it should. My question is, by updating activity.Student.Name, how can I detect change in Activity entity and not in Student entity? Is there any support in Entity Framework to detect changes in the parent table (and not in the slave table, where actual change goes though).??
Please help, it will save me a lot of time..
Even though this is an older question I thought I would give an answer anyway. NO you cannot.
The reasoning behind this is that you the programmer, as far as the code example goes is aware what is happening and could act on that (before doing the SaveChanges) to make sure whatever you want to happen is going to happen.
The Student you are changing might also be part of other entities, so would you also want those entities to be notified. An automatic behavior as you suggest would result in very complex notifications begin sent through the model which is (in most cases undesirable).
As #Ladislav Mrnka also indicated youy did not change the activity, but a Student involved in the activity. If the student relation is more than a simple lookup perhaps the model should be changed. Form the sample code given it is hard to see "why" you would need to detect changes made "through" other entities