EF6 Effort: seeding data leads to wrong ID's - entity-framework-6

I'm using Effort 2.2.13.0 in my unit test project (xUnit). In a fixture, I'm adding company data to the Company table in the in-memory database.
CompanyId = 1, Name = "Company 1"
CompanyId = 2, Name = "Company 2"
CompanyId = 3, Name = "Company 3"
The strange behaviour is that after calling SaveChanges to store the data to the database, Company 2 has id 3 and Company 3 has id 2.
The fixture:
public class SharedDatabaseFixture
{
public SharedDatabaseFixture()
{
var connection = DbConnectionFactory.CreateTransient();
Context = new TestDbContext(connection);
Seed();
}
public TestDbContext Context { get; }
private void Seed()
{
var addresses = AddressSeed.Get();
var countries = CountrySeed.Get();
var stores = StoreSeed.Get();
var companies = CompanySeed.Get();
var products = ProductSeed.Get();
Context.Countries.AddRange(countries);
Context.Companies.AddRange(companies);
<!-- companies list is still correct -->
Context.SaveChanges();
<!-- Company 2 has id 3, company 3 has id 2 -->
}
}
I'm presetting the id's in the companies list, I also tried leaving them empty, but the result is the same.
Anyone seen this odd behaviour before?

Related

How to get relationships with properties from Neo4jClient

After some struggle to get it right I manage to save relationships with properties to a Neo4j db with Neo4jClient. The problem arrises when I want to read those relationships back. Suddenly the query which worked like a charm before does not return my users anymore? No exceptions are thrown, the call just silently returns empty :( I read about possible deserializing problems and added the parameterless constructor to the relationship class but no luck.
public class UserHasHomeCity : Relationship<HasHomeCity>, IRelationshipAllowingSourceNode<UserEntity>, IRelationshipAllowingTargetNode<CityEntity>
{
public UserHasHomeCity()
: base(-1, null)
{
}
public UserHasHomeCity(NodeReference targetNode, HasHomeCity data)
: base(targetNode, data)
{
}
public const string TypeKey = "USER_HAS_HOME_CITY";
public override string RelationshipTypeKey
{
get { return TypeKey; }
}
}
public class HasHomeCity
{
public string Date { get; set; }
public HasHomeCity()
{ }
public HasHomeCity(string date)
{
this.Date = date;
}
}
And here is my query:
var graphResults = graphClient.Cypher
.Match("(user:User)-[:USER_IS_IN_ROLE]-(role:Role)",
"(user:User)-[:USER_HAS_HOME_CITY]-(homeCity:City)-[:CITY_IS_IN_COUNTRY]-(homeCountry:Country)",
"(user:User)-[:USER_HAS_LIVING_CITY]-(livingCity:City)-[:CITY_IS_IN_COUNTRY]-(livingCountry:Country)")
.Where((UserEntity user) => user.Id == id)
.Return((user, role, homeCity, livingCity, homeCountry, livingCountry) => new
{
User = user.As<UserEntity>(),
Roles = role.CollectAs<RoleEntity>(),
HomeCity = homeCity.As<CityEntity>(),
LivingCity = livingCity.As<CityEntity>(),
HomeCountry = homeCountry.As<CountryEntity>(),
LivingCountry = livingCountry.As<CountryEntity>()
}).Results;
Neo4jClient is moving away from using Relationship and Node classes where possible, so, the good news is - you don't need to define your relationships as : Relationship any more! In fact, depending on how far you want to take it, you don't even need your UserHasHomeCity class at all!
Relationship properties are treated the same as nodes, in the sense that they are just POCO objects.
So, to create (as I'm sure you know) we do something like:
var userData = new User {Id = "Id-1"};
var cityData = new City {Name = "Brighton"};
var countryData = new Country {Name = "UK"};
var userHasHomeData = new HasHomeCity {Date = "April 1980"};
var generalData = new CountryRelationshipData { Area = "South Coast" };
gc.Cypher
.Create("(country:Country {countryParams})")
.WithParam("countryParams", countryData)
.ExecuteWithoutResults();
gc.Cypher
.Match("(country:Country)")
.Where((Country country) => country.Name == "UK")
.CreateUnique("(city:City {cityParams})-[:CITY_IS_IN_COUNTRY {relParams}]->(country)")
.WithParam("cityParams", cityData)
.WithParam("relParams", generalData)
.ExecuteWithoutResults();
gc.Cypher
.Match("(city:City)")
.Where((City city) => city.Name == "Brighton")
.Create("(user:User {userParams})-[:USER_HAS_HOME_CITY {relParams}]->(city)")
.WithParam("userParams", userData)
.WithParam("relParams", userHasHomeData )
.ExecuteWithoutResults();
which will give us a (User)-[:USER_HAS_HOME_CITY]-(City) structure.
To retrieve the relationship properties, we can use this query:
var query = gc.Cypher
.Match("(user:User)-[r:USER_HAS_HOME_CITY]-(city:City)-[r1:CITY_IS_IN_COUNTRY]-(country:Country)")
.Where((User user) => user.Id == "Id-1")
.Return((user, city, r, country, r1) =>
new
{
User = user.As<User>(),
City = city.As<City>(),
HasHome = r.As<HasHomeCity>(),
Country = country.As<Country>(),
CountryRel = r1.As<CountryRelationshipData>()
});
and looping through the results (all 1 of them in this case):
var res = query.Results.ToList();
foreach (var result in res)
Console.WriteLine("User ({0}) home city: {1} (which is in {2}, {3}) since {4}", result.User.Id, result.City.Name,result.CountryRel.Area, result.Country.Name, result.HasHome.Date );
will give us:
User (Id-1) home city: Brighton (which is in South Coast, UK) since April 1980
as the output.

How to Query Icollections of Entity Framework Code First Data

I'm following this post here
his code looks like so
from p in ctx.Persons
where p.ID == personId
select new PersonInfo
{
Name = p.FirstName + " " + p.LastName,
BornIn = p.BornInCity.Name,
LivesIn = p.LivesInCity.Name,
Gender = p.Sex.Name,
CarsOwnedCount = p.Cars.Count(),
}
Now when he is using p.LivesInCity.Name ( My Assumption is that he has 2 different ViewModels Classes and 1 of them has an IEnumerable or some sort of collection of City names?)
Question
How can he access p.LivesInCity.Name but when i Try p.Countys.[CountyColectionForSections].[SectionProperty] I get See Image Below
here is how i setup my ViewModels
Table 1
public string Client { get; set; }
public virtual ICollection<dbProspect> Prospects { get; set; }
Table 2
public int Prospect { get; set; }
public virtual ICollection<dbCounty> Countys { get; set; }
public virtual ICollection<UserProfiles> UserProfiles { get; set; }
Table 3...
Table 3 Would have a collection of another table, and table 4 would have another colection and so on Basically a Table Hierarchy about 15 deep.
here is how i try and access them
var x = from c in db.Client
select new ViewModelExcelReport
{
client = c.ClientName,
cntyCounty = p.Countys. //Here is where i would like to say p.Countys.[CountyProperty]
sctSection = p.Countys.[CountyColectionForSections].[SectionProperty]
}
You could do the following if you expect only one County per Client and I'm guessing at the relation between the entities:
var x = from c in db.Client
from p in c.Prospects
from ct in p.Countys
select new ViewModelExcelReport
{
client = c.ClientName,
cntyCounty = ct.County,
sctSection = ct.Section
};
The first example works because he's only referencing a single instance of an entity (LivesIn of type City), and then referencing a single primitive value within (Name property is just a string).
I see you're trying to project a new type by referencing an IEnumerable (Countys), but you never actually enumerate/iterate/materialize an instance.
p.Countys.[CountyProperty] will never exist, because you have a reference to a collection and you must get a reference to a single object first. You can do that by using Countys.Single() or SingleOrDefault() but I doubt that's what you want. I think what you want is to traverse the model in the opposite direction. From the "Many" side to the "One" side. Something like this:
var x = from c in db.County
select new ViewModelExcelReport
{
County = c.Name,
CountyProperty = c.AnyProperty,
Section = c.Section.Name,
Prospect = c.Prospect.Name,
Client = c.Prospect.Client.Name
}

mvc entity framework many to many user and role insert

I have an mvc project with database first entityframework. In Project I have 3 tables.
Users >>> UsersInRoles <<< Roles with many to many relationship.
and my CreateUser codes below;
public bool CreateUser(string email, string password, string birthday,string firstname,string lastname)
{
bool result;
var dogumgunu = Convert.ToDateTime(birthday);
var sifre = FormsAuthentication.HashPasswordForStoringInConfigFile(password, "sha1");
var confirmation = CreateConfirmationToken(email);
try
{
var user = new User
{
UserName = email,
Password = sifre,
UserJoinDate = DateTime.Now,
UserBirthDay = dogumgunu,
UserConfirmationToken = confirmation,
UserID = Guid.NewGuid(),
MemberFirstName = firstname,
MemberLastName = lastname
};
var role = new Role
{
RoleName = "Client"
};
user.Roles.Add(role); //problem is here!!!!!!!!!
_bb.Users.AddObject(user);
_bb.SaveChanges();
result = true;
}
catch (Exception)
{
result = false;
}
return result;
}
In this code I am new user creating. And I am adding a role. But This code include a new Role in Roles table. I dont want to this. I want to just add UsersInRoles table a new user. What is wrong? Thanks for reply.
Swap these two lines:
_bb.Users.AddObject(user);
user.Roles.Add(role);
because AddObject converts the whole object graph to the Added state. If you add the role afterwards, its state will remain Unchanged.
And you should fetch the role from the database first or create a Role object that only has an existing RoleId. (A so called stub entity).
So in stead of new Role you could do
var role = _bb.Roles.Single(r => r.RoleName == "Client");

using GroupPrincipal can you get additional info from UserPrincipal

I am looking up users who are members of an AD group using GroupPrincipal.
GroupPrincipal group = GroupPrincipal.FindByIdentity(pc, "Advisors");
I need to get the EmployeeID field from this lookup but I believe this is only possible using UserPrincipal.
var members = group.Members.Select(x => new DomainContext() { EmployeeID = x.EmployeeId, FullName = x.DisplayName }).ToList();
Does anyone know of a way round this?
You have to use UserPrincipal unless you're using the underlying DirectoryEntry/DirectorySearcher classes.
You should use .GetMembers() instead of .Members then you can do stuff like:
var userMembers = group.GetMembers().OfType<UserPrincipal>();
foreach( var member in userMembers) {
string empid = member.EmployeeId; //do something with the EmployeeId
}

MVC 3 Reusable Remote Validation with DB Lookup

I have an MVC 3 appliation which I have many integer fields on a form. They all require range validation but the ranges exists in a table in my database. So I would like to create a reusable remote validation tool which will look up the min and max value and return the validation to the view.
I am updating this with some example code of what I would like to do to see my request might clarify what I am looking for:
In my validation class:
[Remote("CheckIntegerRange", "Validation", ErrorMessage = "Value outside of range")]
public object UW1_Web_Tension_SP { get; set; }
[Remote("CheckIntegerRange", "Validation", ErrorMessage = "Value outside of range")]
public object UW2_Web_Tension_SP { get; set; }
[Remote("CheckIntegerRange", "Validation", ErrorMessage = "Value outside of range")]
public object UW3_Web_Tension_SP { get; set; }
In my ValidationController I tried to create a function with multiple parameters but I dont think I can - however I think it shows what I am trying to do more clearly:
public class ValidationController : Controller
{
public JsonResult CheckIntegerRange(int integer, string EntityName, string AttributeName)
{
var result = false;
int MinInteger = 0;
int MaxInteger = 100;
//declare recipe entities
var context = new MadicoRecipeEntities();
//set sql statements and get description, etc from attributes view
var esqlIntegerAttributeDetails = "SELECT VALUE c FROM MadicoRecipeEntities.v_AttributeIntegerRangeDetails AS c " +
"WHERE c.EntityName = '" + EntityName + "' AND c.Attribute = '" + AttributeName + "'";
var queryAttributeDetails = context.CreateQuery<v_AttributeIntegerRangeDetails>(esqlIntegerAttributeDetails);
var RecipeAttributes = queryAttributeDetails.ToList();
foreach (var AttributeDetails in RecipeAttributes)
{
MinInteger = AttributeDetails.Min;
MaxInteger = AttributeDetails.Max;
}
return Json(result, JsonRequestBehavior.AllowGet);
}
}
I have found the following post on the asp.net forums which handled my first obstacle - passing different named attributes to the same validator. However, in this example the name is passed in generically - I need to have the name in order to query the table to get the applicable min and max ranges.
http://forums.asp.net/t/1625928.aspx/3/10
Can anyone point me in the right direction?
Thanks!
It is called remote validation! Here is an example:
remote validation

Resources