The relationship between the two objects cannot be defined - why? - c#

I am submitting a form that contains a user id and a pipe-delimited set of numbers.
The model looks like this:
public class SeasonPassData
{
public int UserID { get; set; }
public string SpaceNumbers { get; set; }
}
That is getting handed off to this controller:
[HttpPost]
public ActionResult SignUp(SeasonPassData data)
{
var user = db.Users.Find(data.UserID);
List<SeasonPass> passes = new List<SeasonPass>();
char[] delimiter = { '|' };
var numbers = data.SpaceNumbers.Split(delimiter).Select(n => Convert.ToInt32(n)).ToArray();
foreach(int number in numbers)
{
passes.Add(new SeasonPass { SpaceNumber=number, User = user });
}
passes.ForEach(p => db.SeasonPasses.Add(p));
db.SaveChanges();
return RedirectToAction("Confirmation", "Home");
}
And should be creating and saving SeasonPasses:
public class SeasonPass
{
public int ID { get; set; }
public int SpaceNumber { get; set; }
public virtual User User { get; set; }
}
However, this - passes.ForEach(p => db.SeasonPasses.Add(p)); keeps raiding this exception:
An exception of type 'System.InvalidOperationException' occurred in
System.Data.Entity.dll but was not handled in user code
Additional information: The relationship between the two objects
cannot be defined because they are attached to different ObjectContext
objects.
How do I fix that?
I tried it with these changes based on a comment. It still doesn't seem to work...
[HttpPost]
public ActionResult SignUp(SeasonPassData data)
{
using(var context = new TTUContext())
{
var user = context.Users.Find(data.UserID);
List<SeasonPass> passes = new List<SeasonPass>();
char[] delimiter = { '|' };
var numbers = data.SpaceNumbers.Split(delimiter).Select(n => Convert.ToInt32(n)).ToArray();
foreach (int number in numbers)
{
passes.Add(new SeasonPass { SpaceNumber = number, User = user });
}
foreach (var pass in passes)
{
context.SeasonPasses.Add(pass);
}
context.SaveChanges();
}
return RedirectToAction("Confirmation", "Home");
}

I'm surprised that what you are doing does not work, but here is a way to sidestep the issue.
Add public int UserID { get; set; } to SeasonPass and set it to assign the relationship instead of setting User.

Related

ML.NET AUC is not defined when there is no positive class in the data Arg_ParamName_Name

I want to use Random Forest method in my project.
I have this error trying to use EvaluateNonCalibrated:
System.ArgumentOutOfRangeException: „AUC is not defined when there is
no positive class in the data Arg_ParamName_Name”
var testSetTransform = _trainedModel.Transform(_dataSplit.TestSet);
return MlContext.BinaryClassification.EvaluateNonCalibrated(testSetTransform);
Here you have models:
public class MLCategoryPrediciton
{
public bool PredictedLabel { get; set; }
}
public class MLFinancialChange
{
[LoadColumn(1)]
public bool Label { get; set; }
[LoadColumn(2)]
public float Value { get; set; }
[LoadColumn(3)]
public float CategoryId { get; set; }
}
And way i preparing data:
public async Task FitAsync()
{
var list = await fcRepository.FindAllAsync();
var output = new List<MLFinancialChange>();
foreach(var item in list)
{
var x = new MLFinancialChange
{
Value = item.Value,
CategoryId = item.Category.Id,
};
output.Add(x);
}
IDataView data = MlContext.Data.LoadFromEnumerable<MLFinancialChange>(output);
DataOperationsCatalog.TrainTestData dataSplit = MlContext.Data.TrainTestSplit(data);
_dataSplit = dataSplit;
var dpp = BuildDataProcessingPipeline();
var tp = dpp.Append(_model);
_trainedModel = tp.Fit(_dataSplit.TrainSet);
}
private EstimatorChain<NormalizingTransformer> BuildDataProcessingPipeline()
{
var dataProcessPipeline = MlContext.Transforms.Concatenate("Features",
nameof(MLFinancialChange.Value),
nameof(MLFinancialChange.CategoryId)
)
.Append(MlContext.Transforms.NormalizeMinMax("Features", "Features"))
.AppendCacheCheckpoint(MlContext);
return dataProcessPipeline;
}
Thanks for help
I just want that to work and i tried to find solution in the internet. Unfortunatelly i spent a lot of time trying fix it.
I've had this problem before, and I think it was because the model wasn't predicting any positive cases. You can try inspecting the predictions and just make sure it's not predicting everything as negative.

MVC C# Saving a list to database

I'm saving properties in my database with the CreateAMeeting method. When I check the database I can see all properties saved except my list, I can't see my list properties in my database. I have been googling but I can't find if it's possible to see them or if I'm just not saving them properly. If I use a breakpoint I can see that the meeting(db.Meetings.Add(meeting);) model have the times i added in the Times list.
When I later try to retrieve my list in the ChooseTimes method, it's null. I don't know if the problem is that I'm saving it wrong or its something else. What am I doing wrong and is it possible to see saved lists in the database?
I'm not done with the fooreachloop, pay no attention to it.
public class MeetingController : BaseController
{
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
public static Meeting NewMeeting;
public static List<DateTime> TempTimes = new List<DateTime>();
public ActionResult CreateMeeting()
{
return View();
}
public ActionResult CreateAMeeting(Meeting meeting)
{
var userName = User.Identity.Name;
var user = db.Users.Where(u => u.UserName == userName).SingleOrDefault();
var model = new MeetingPeopleViewModel();
meeting.Creator = user;
meeting.Invited.Add(user);
meeting.Times = TempTimes;
meeting.Start = DateTime.Now;
meeting.End = meeting.Start.AddMinutes(meeting.Minutes);
db.Meetings.Add(meeting);
db.SaveChanges();
return View("AddToMeeting", model);
}
public ActionResult AddTempTime(DateTime Start, Meeting meeting)
{
TempTimes.Add(Start);
meeting.Times = TempTimes;
return View("CreateMeeting", meeting);
}
public ActionResult ChooseTimes()
{
var userName = User.Identity.Name;
var user = db.Users.Where(u => u.UserName == userName).SingleOrDefault();
Meeting meeting = new Meeting();
foreach(var item in db.Meetings)
{
if(item.Invited.Contains(user))
{
meeting = item;
}
}
return View(meeting);
}
This is my Meeting model.
public class Meeting
{
public int Id { get; set; }
public string Title { get; set; }
public ApplicationUser Creator { get; set; }
public ICollection<ApplicationUser> Invited { get; set; }
public double Minutes { get; set; }
public DateTime Start { get; set; }
public DateTime End { get; set; }
public ICollection<DateTime> Times { get; set; }
public bool AllDay { get; set; }
public ICollection<ApplicationUser> User { get; set; }
public ApplicationUser UserNotis { get; set; }
}
As far as Im aware you can not save a literal list to a database, you can save all the items in a list to a database, by iterating through the list and saving each unique record.
public class MeetingController : BaseController
{
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
public static Meeting NewMeeting;
public static List<DateTime> TempTimes = new List<DateTime>();
public ActionResult CreateMeeting()
{
return View();
}
public ActionResult CreateAMeeting(Meeting meeting)
{
var userName = User.Identity.Name;
var user = db.Users.FirstOrDefault(u => u.UserName == userName);
var model = new MeetingPeopleViewModel();
meeting.Creator = user;
meeting.Invited.Add(user);
meeting.Times = TempTimes;
meeting.Start = DateTime.Now;
meeting.End = meeting.Start.AddMinutes(meeting.Minutes);
db.Meetings.Add(meeting);
db.SaveChanges();
return View("AddToMeeting", model);
}
public ActionResult AddTempTime(DateTime Start, Meeting meeting)
{
TempTimes.Add(Start);
meeting.Times = TempTimes;
return View("CreateMeeting", meeting);
}
public ActionResult ChooseTimes()
{
var userName = User.Identity.Name;
var user = db.Users.FirstOrDefault(u => u.UserName == userName);
Meeting meeting = new Meeting();
List<Meeting> Meetings = db.Meetings.ToList();
foreach (var item in Meetings)
{
if (item.Invited.Contains(user))
{
meeting = item;
}
}
return View(meeting);
}
There are better ways to do multiple things you are trying to do, but this will solve your issue.
You have to create a list of the meetings populated from the database so it is an Enumerable at the time you iterate rather than an query able,
I tried to save my entire list in one field, wich obviusly isn't possible. So i had to create a new model with a database to save evrything in my list. Here is my save method if anyone else is having problems saving items in a list.
public void SaveTimes(Meeting meeting)
{
foreach (var time in TempStart)
{
var mt = new MeetingTimes
{
MeetingId = meeting.Id,
Meeting = meeting,
Time = time
};
db.MeetingTimes.Add(mt);
db.SaveChanges();
}
}

Why isn't this Sum() in my index working?

I have the following test:
public class ListingEventTest
{
public ListingEventTest()
{
Artists = new List<ArtistTest>();
}
public List<ArtistTest> Artists { get; set; }
public string Id { get; set; }
public string Name { get; set; }
public double Popularity { get; set; }
}
public class ArtistTest
{
public string Id { get; set; }
public Stat Stats { get; set; }
}
public class Stat
{
public double Popularity { get; set; }
}
public class ArtistsWithStats_ByName : AbstractIndexCreationTask<ListingEventTest>
{
public ArtistsWithStats_ByName()
{
Map = listingEvents => from listingEvent in listingEvents
let artists = LoadDocument<ArtistTest>(listingEvent.Artists.Select(x => x.Id))
select new
{
Popularity = artists.Average(x => x.Stats.Popularity),
listingEvent.Name
};
}
}
[TestFixture]
public class IndexCanDoSums
{
[Test]
public async void WhenListingEventArtistsHaveStatsIndexReturnsPopularity()
{
var store = new EmbeddableDocumentStore
{
UseEmbeddedHttpServer = true,
Configuration =
{
RunInUnreliableYetFastModeThatIsNotSuitableForProduction = true,
RunInMemory = true,
}
}.Initialize();
IndexCreation.CreateIndexes(typeof(ArtistsWithStats_ByName).Assembly, store);
using (var session = store.OpenAsyncSession())
{
for (int i = 0; i < 10; i++)
{
var le = new ListingEventTest
{
Name = "test-" + i
};
await session.StoreAsync(le);
for (int j = 0; j < 2; j++)
{
var artist = new ArtistTest
{
Stats = new Stat
{
Popularity = 0.89d
}
};
await session.StoreAsync(artist);
le.Artists.Add(artist);
}
await session.SaveChangesAsync();
}
}
Thread.Sleep(2000);
using (var session = store.OpenAsyncSession())
{
var query = session
.Advanced.AsyncLuceneQuery<ListingEventTest>("ArtistsWithStats/ByName");
var result = await query.ToListAsync();
result.First().Popularity.Should().NotBe(0);
}
}
}
When I query this index Popularity is always 0.
Any ideas?
Some funny things going on here.
First, you are storing ArtistTest under the ListingEventTest document, not as separate documents, so in your index there is no need to call LoadDocument, you could just do:
from listingEvent in listingEvents
from artist in listingEvent.Artists
select ...
Second, a Map-only index is a lot like a SQL index where you're just calling out the columns you want to be able to query on. Here, you're doing a calculation on a set of buried properties and you have a top-level property where you want to store that information, but how that ends up working is that your calculated property value goes into the Lucene index (so you could query by Popularity if you want) but the data that is returned is straight from the unaltered document. The map defines what goes into Lucene, which points to the document id, and then the document store returns the documents as the results.
This could be modified somewhat by calling Store(x => x.Popularity) in the index's constructor, which would store the value to be recalled later, but honestly offhand I'm not sure if your calculated value or the document's value (which is zero) would win.
Given that, it becomes pretty confusing to have a document property for the sole purpose of trying to fill it during indexing, which is why it's usually a better option to have a class that represents the mapped state, and then implementing AbstractIndexCreationTask<TDocument, TReduceResult> where the TReduceResult class would only contain the result of your mapping, namely the Name and Popularity columns.
Then when you query from, you can use .ProjectFromIndexFieldsInto<T>() to get your results from the stored index results, not from the document store.

make a dropdown from string type in mvc 4

model code....
public class ConfigureModel
{
public bool Responsive { get; set; }
public string Theams { get; set; }
}
controller
ConfigureModel model = new ConfigureModel();
model.Responsive = bootStrapCoreSettings.Responsive ;
//model.Theams = bootStrapCoreSettings.Theams;
var theams = "lsdjfldsk;lkdfjlsd;jldskfj;dlksfj;";
model.Theams = them.Split(new char[] { ';' });
how to put theams values in to dropdown...
need a guideline or code
For using the Html.Dropdownlist in your view you need to have a IEnumerable<SelectListItem> selectList in your model. So your model will change like this:
public class ConfigureModel
{
public bool Responsive { get; set; }
public IEnumerable<string> TheamsList { get; set; }
}
Your controller will have :
var theams = "lsdjfldsk;lkdfjlsd;jldskfj;dlksfj;";
List<string> myList = theams.TrimEnd(';').Split(';').ToList();
model.TheamsList = myList;
After you have filled your model, code in the Razor view will be like:
#Html.DropDownListFor("Theams", Model.TheamsList)
Model Code
public class ConfigureModel
{
public bool Responsive { get; set; }
public SelectList TheamsList { get; set; }
public string SelectedTheam { get; set; }
}
Action Code
ConfigureModel model = new ConfigureModel();
var theams = "lsdjfldsk;lkdfjlsd;jldskfj;dlksfj;";
// If you don't want a blank value for the bit after the last ';'
theams = theams.TrimEnd(';');
var theamsSplit = theams.Split(new char[] { ';' }).ToDictionary(s => s, s => s);
model.TheamsList = new SelectList(theams, "Key", "Value");
View Code
#Html.DropDownListFor(m => m.SelectedTheam, Model.TheamsList)
Tangent: Did you mean Themes instead of Theams?
Your code does not even compile:
// You try to assign an array to a string
model.Theams = them.Split(new char[] { ';' });
Try changing the configure model class to:
public class ConfigureModel
{
public bool Responsive { get; set; }
public List<string> Theams { get; set; }
}
and your calling code to something like (sample to demonstrate not best practice);
var theams = "lsdjfldsk;lkdfjlsd;jldskfj;dlksfj;";
theams.Split(new char[] { ';' }).ToList().ForEach(theam => {
model.Theams.Add(theam);
});
Then you have a filled model. Use this in your razor view:
#Html.DropDownListFor( m => m.Theams, new SelectList(Model.Theams))
In your code,
model.Theams should be of array type.
after converting it to List or array just pass it to #HTML.EditorFor(model=> Theams)
it will be dropdown.

RavenDb how do I reduce group values into collection in reduce final result?

I hope it's more clear what I want to do from the code than the title. Basically I am grouping by 2 fields and want to reduce the results into a collection all the ProductKey's constructed in the Map phase.
public class BlockResult
{
public Client.Names ClientName;
public string Block;
public IEnumerable<ProductKey> ProductKeys;
}
public Block()
{
Map = products =>
from product in products
where product.Details.Block != null
select new
{
product.ClientName,
product.Details.Block,
ProductKeys = new List<ProductKey>(new ProductKey[]{
new ProductKey{
Id = product.Id,
Url = product.Url
}
})
};
Reduce = results =>
from result in results
group result by new {result.ClientName, result.Block} into g
select new BlockResult
{
ClientName = g.Key.ClientName,
Block = g.Key.Block,
ProductKeys = g.SelectMany(x=> x.ProductKeys)
};
}
I get some weird System.InvalidOperationException and a source code dump where basically it is trying to initialize the list with an int (?).
If I try replacing the ProductKey with just IEnumerable ProductIds (and make appropriate changes in the code). Then the code runs but I don't get any results in the reduce.
You probably don't want to do this. Are you really going to need to query in this manner? If you know the context, then you should probably just do this:
var q = session.Query<Product>()
.Where(x => x.ClientName == "Joe" && x.Details.Block == "A");
But, to answer your original question, the following index will work:
public class Products_GroupedByClientNameAndBlock : AbstractIndexCreationTask<Product, Products_GroupedByClientNameAndBlock.Result>
{
public class Result
{
public string ClientName { get; set; }
public string Block { get; set; }
public IList<ProductKey> ProductKeys { get; set; }
}
public class ProductKey
{
public string Id { get; set; }
public string Url { get; set; }
}
public Products_GroupedByClientNameAndBlock()
{
Map = products =>
from product in products
where product.Details.Block != null
select new {
product.ClientName,
product.Details.Block,
ProductKeys = new[] { new { product.Id, product.Url } }
};
Reduce = results =>
from result in results
group result by new { result.ClientName, result.Block }
into g
select new {
g.Key.ClientName,
g.Key.Block,
ProductKeys = g.SelectMany(x => x.ProductKeys)
};
}
}
When replicating I get the same InvalidOperationException, stating that it doesn't understand the index definition (stack trace omitted for brevity).
Url: "/indexes/Keys/ByNameAndBlock"
System.InvalidOperationException: Could not understand query:
I'm still not entirely sure what you're attempting here, so this may not be quite what you're after, but I managed to get the following working. In short, Map/Reduce deals in anonymous objects, so strongly typing to your custom types makes no sense to Raven.
public class Keys_ByNameAndBlock : AbstractIndexCreationTask<Product, BlockResult>
{
public Keys_ByNameAndBlock()
{
Map = products =>
from product in products
where product.Block != null
select new
{
product.Name,
product.Block,
ProductIds = product.ProductKeys.Select(x => x.Id)
};
Reduce = results =>
from result in results
group result by new {result.Name, result.Block}
into g
select new
{
g.Key.Name,
g.Key.Block,
ProductIds = g.SelectMany(x => x.ProductIds)
};
}
}
public class Product
{
public Product()
{
ProductKeys = new List<ProductKey>();
}
public int ProductId { get; set; }
public string Url { get; set; }
public string Name { get; set; }
public string Block { get; set; }
public IEnumerable<ProductKey> ProductKeys { get; set; }
}
public class ProductKey
{
public int Id { get; set; }
public string Url { get; set; }
}
public class BlockResult
{
public string Name { get; set; }
public string Block { get; set; }
public int[] ProductIds { get; set; }
}

Categories

Resources