Sequence contains more than one matching element - EF Database Initialize - c#

I am working on a system that generates a database on initialization:
public static void initialiseEntityFramework()
{
using (DbContextentityframework context = new DbContextentityframework())
{
context.Database.Initialize(true);
}
}
but when it gets to the initialization is returns the error:
System.InvalidOperationException: 'Sequence contains more than one
matching element'
Stack Trace:
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)
at System.Data.Entity.ModelConfiguration.Configuration.Mapping.ForeignKeyPrimitiveOperations.<>c__DisplayClass4a.<RemoveAllForeignKeyConstraintsForColumn>b__47(ForeignKeyBuilder fk)
at System.Data.Entity.Utilities.IEnumerableExtensions.Each[T](IEnumerable`1 ts, Action`1 action)
at System.Data.Entity.ModelConfiguration.Configuration.Mapping.EntityMappingConfiguration.CleanupUnmappedArtifacts(DbDatabaseMapping databaseMapping, EntityType table)
at System.Data.Entity.ModelConfiguration.Configuration.Mapping.EntityMappingConfiguration.Configure(DbDatabaseMapping databaseMapping, ICollection`1 entitySets, DbProviderManifest providerManifest, EntityType entityType, EntityTypeMapping& entityTypeMapping, Boolean isMappingAnyInheritedProperty, Int32 configurationIndex, Int32 configurationCount, IDictionary`2 commonAnnotations)
at System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.ConfigureTablesAndConditions(EntityTypeMapping entityTypeMapping, DbDatabaseMapping databaseMapping, ICollection`1 entitySets, DbProviderManifest providerManifest)
at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.ConfigureEntityTypes(DbDatabaseMapping databaseMapping, ICollection`1 entitySets, DbProviderManifest providerManifest)
at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.Configure(DbDatabaseMapping databaseMapping, DbProviderManifest providerManifest)
at System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo)
at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)
at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input)
at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
at System.Data.Entity.Internal.LazyInternalContext.MarkDatabaseInitialized()
at System.Data.Entity.Database.Initialize(Boolean force)
When the above context.Database.Initialize(True); code runs, during initialization my debugger takes to to a method that runs through 400+ instances of applying classes to a DBModelBuilder. It seems nearly all of these are fine, however there are a few instances that cause the error I am seeing. Here is an example of such an instance:
modelBuilder.Entity<Genesis_Core_Meta.#Workers.Sources.#Worker>().Map(m =>
{
m.MapInheritedProperties();
m.ToTable("Worker", "Workers");
})
.Property(p => p.ContactId)
.HasDatabaseGeneratedOption(
System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity
);
Where Worker class inherits from an Individual class which inherits from a Contact class. Each of these classes are pretty big with lots of properties and methods.
I was wondering if someone might be able to tell from the above what I might need to look for in these classes to spot what could be causing the problem?
Still a bit tenuous I know but I'm hopeful someone can help!

Related

Entity Framework Core: NullReferenceException after DropTable

I am simply trying to drop a table.
First I tried to just remove all the references to the table in the code. When creating a new migration, I get a "NullReferenceException", as shown here.
Then I tried instead to create an empty migration with migrationBuilder.DropTable("MyTable") in the Up() method. That drops the table, but if I try to make a new empty migration I get the same error.
Are these not the ways to drop a table with EF Core? Do I need something else, or doing something in the wrong order?
I am using F#, but I hope that is not the problem.
Build started...
Build succeeded.
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Initialize(ColumnOperation columnOperation, IColumn column, RelationalTypeMapping typeMapping, Boolean isNullable, IEnumerable`1 migrationsAnnotations, Boolean inline)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Add(IColumn target, DiffContext diffContext, Boolean inline)+MoveNext()
at Pomelo.EntityFrameworkCore.MySql.Migrations.Internal.MySqlMigrationsModelDiffer.PostFilterOperations(IEnumerable`1 migrationOperations)+MoveNext()
at System.Linq.Enumerable.SelectManySingleSelectorIterator`2.MoveNext()
at System.Linq.Enumerable.CastIterator[TResult](IEnumerable source)+MoveNext()
at System.Collections.Generic.List`1.InsertRange(Int32 index, IEnumerable`1 collection)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Add(ITable target, DiffContext diffContext)+MoveNext()
at Pomelo.EntityFrameworkCore.MySql.Migrations.Internal.MySqlMigrationsModelDiffer.PostFilterOperations(IEnumerable`1 migrationOperations)+MoveNext()
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.DiffCollection[T](IEnumerable`1 sources, IEnumerable`1 targets, DiffContext diffContext, Func`4 diff, Func`3 add, Func`3 remove, Func`4[] predicates)+MoveNext()
at System.Linq.Enumerable.ConcatIterator`1.MoveNext()
at Pomelo.EntityFrameworkCore.MySql.Migrations.Internal.MySqlMigrationsModelDiffer.PostFilterOperations(IEnumerable`1 migrationOperations)+MoveNext()
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.Sort(IEnumerable`1 operations, DiffContext diffContext)
at Microsoft.EntityFrameworkCore.Migrations.Internal.MigrationsModelDiffer.GetDifferences(IRelationalModel source, IRelationalModel target)
at Microsoft.EntityFrameworkCore.Migrations.Design.MigrationsScaffolder.ScaffoldMigration(String migrationName, String rootNamespace, String subNamespace, String language)
at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType, String namespace)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType, String namespace)
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigration.<>c__DisplayClass0_0.<.ctor>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Object reference not set to an instance of an object.

"Object reference not set to an instance of an object" - but nothing is null?

Yeah, you probably think; "God, another one?".
Yes, another one.
"Object reference not set to an instance of an object."
I've been working with EF6 lately and after developing for some time, I found that a little bit more optimization was needed. Alot has been reworked without problems, but it seems I can't figure out this one.
In my application I've been using this piece of pseudo code to get items from the database.
DbContext context = new DbContext();
public IEnumerable<string> GetExistingNames(IEnumerable<string> names)
{
foreach(string name in names)
{
string existingName = context.Names.Where(n => n.Name == name).FirstOrDefault();
if(existingName == null) continue;
yield return existingName;
}
}
Note that the DbContext is only there for clarification. It gets disposed when it's needed.
This approach "works" but it would mean that if I had, say, 20 names to look up, I would hit the database for about 20 times. Ouch!
Therefore I started looking for a way to implement a single query. I've found a way, but it's not really working as it should. This is my current approach;
public IEnumerable<string> GetExistingNames(ICollection<string> names)
{
IQueryable<Names> query = context.Names.Where(n => names.Contains(n.Name));
if(query == null) yield break;
foreach(var name in query)
{
yield return name.Name;
}
}
This should, to my knowledge, translate in SELECT ... FROM Names WHERE ... IN (...). However, my application crashes at foreach(var name in query) as soon as it hits name, throwing the feared NullReferenceException.
It does, however, pass if(query == null), meaning the query is not null. At this point, I was confused. How can it not be null, but still throw this error?
I was not sure if the query gets executed if I try to access it with this approach. Therefore, I tried to create a list from the query using ToList(), but this throws the same exception upon creating the list.
It seems like everytime I make a call to query, it gives me a NullReferenceException. However, it still passes if(query == null). So, my question is;
Why is it passing the test, but is it not accessible? Did I misinterpret IQueryable<>? And if I did misinterpret it, how should it be done properly?
EDIT
I have debugged before posting. I know for sure that;
names is not null.
context is not null.
Code calling the function:
//A wrapper for the DbContext. This is only used for some methods
//which require the DbContext
DbContextWrapper wrapper = new DbContextWrapper();
public void ProcessNames(List<string> inputNames)
{
//...
foreach(string existingName in wrapper.GetExistingNames(inputNames))
{
//Do something with the names
}
//...
}
EDIT 2
After some more debugging, I found that the query being created is somewhat different. It is supposed to be;
SELECT `Extent1`.`Name`
FROM `Names` AS `Extent1`
WHERE (`Extent1`.`Name` IN ( #gp1,#gp2))
However, I get this;
System.Data.Entity.Infrastructure.DbQuery<MyDbContext.Names>
As the actual query.
The stack trace;
at MySql.Data.Entity.SqlGenerator.Visit(DbPropertyExpression expression)
at MySql.Data.Entity.SqlGenerator.Visit(DbInExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbInExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SqlGenerator.VisitBinaryExpression(DbExpression left, DbExpression right, String op)
at MySql.Data.Entity.SqlGenerator.Visit(DbAndExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbAndExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SelectGenerator.Visit(DbFilterExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbFilterExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SqlGenerator.VisitInputExpression(DbExpression e, String name, TypeUsage type)
at MySql.Data.Entity.SelectGenerator.VisitInputExpressionEnsureSelect(DbExpression e, String name, TypeUsage type)
at MySql.Data.Entity.SelectGenerator.Visit(DbProjectExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbProjectExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SelectGenerator.GenerateSQL(DbCommandTree tree)
at MySql.Data.MySqlClient.MySqlProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree)
at System.Data.Entity.Core.Common.DbProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver, BridgeDataReaderFactory bridgeDataReaderFactory, ColumnMapFactory columnMapFactory)
at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateCommandDefinition(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver)
at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.CreateCommandDefinition(ObjectContext context, DbQueryCommandTree tree)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Boolean streaming, Span span, IEnumerable`1 compiledQueryParameters, AliasGenerator aliasGenerator)
at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__6()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClass7.<GetResults>b__5()
at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at MyNameSpace.DbContextWrapper.<GetExistingNames>d__1b.MoveNext() in c:~omitted~\DbContextWrapper.cs:line 70
at MyNameSpace.NameProcessor.ProcessNames(List<string> inputNames) in c:~omitted~\NameProcessor.cs:line 60
After you posted stacktrace I spotted that you using MySQL and so my guess is that you hit this bug: Exception when using IEnumera.Contains(model.property) in Where predicate
So solution would be to ensure you have versions of MySQL Connector/NET 6.7.6 / 6.8.4 / 6.9.5 and newer.
Or try to use Any method instead of Contains.
P.s. This bug report came from this post by Alnedru: Int[].Contains doesn't work in EF6
Your null check on query will never fail, because it's returning the IQueryable object (that is, the query being built). You've instantiated it and started building a query, so it will always pass.
To be clear - IQueryable is roughly equivalent to a string containing the ADO.Net Select statement. It is not, inherently, the actual data.
This doesn't explain why it's throwing a null exception, but it does explain why the null check passes, and the foreach could still fail.
EDIT: When attempting to duplicate this, I found that I get an exception when using the below code:
public IEnumerable<string> GetExistingNames(ICollection<string> names)
{
IQueryable<Names> query = Names.Where(n => names.Contains(n.Name));
if (query == null) yield break;
foreach (var name in query)
{
yield return name.Name;
}
}
It wasn't a NullReferenceException, but a NotSupportedException, as ICollections Contains has no supported translation to SQL. Switching the parameter to List caused the problem to disappear:
public IEnumerable<string> GetExistingNames(List<string> names)
Or you can convert it to a list on the fly:
IQueryable<Names> query = Names.Where(n => names.ToList().Contains(n.Name));
Why don't you just add an extension method to alleviate the stress this brings you.
try this piece of code
namespace HelperExtensionMethods
{
public static class ExtensionMethods
{
public static string UpdateNullString(this string testNullstring)
{
if (TestNullstring == null)
return "";
return Testullstring;
}
}
}
and then call it like so
using HelperExtesionMethods
DbContext context = new DbContext();
public IEnumerable<string> GetExistingNames(ICollection<string> names)
{
IQueryable<Names> query = context.Names.Where(n => names.UpdateNullString().Contains(n.Name.UpdateNullString()));
if(query == null) yield break;
foreach(var name in query)
{
yield return name.Name;
}
}

Int[].Contains doesn't work in EF6

I have a strange issue, basically i have this code:
var langauges = (from l in context.languages
where Model.LanguageIDs.Contains(l.LanguageID)
select l)
.ToList<language>();
I don't know why but I Always get an error:
System.NullReferenceException: Object reference not set to an instance of an object
The thing is it was working before, but after that i've upgraded all my application to MVC5 and EF6, it started to crash on this code.
Although if I check the Model.Langauges, it has several ID's so it is ok.
I also looped through tall the context.Languages and all of them have id's.
I also wrote like this:
var langauges = (from l in context.languages
where 1==l.LanguageID
select l)
.ToList<language>();
And this WORKS also, so i really don't get it, what am i doing wrong?
Anyone can elaborate ...?
StackTrace:
at MySql.Data.Entity.SqlGenerator.Visit(DbPropertyExpression expression)
at MySql.Data.Entity.SqlGenerator.Visit(DbInExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbInExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SqlGenerator.VisitBinaryExpression(DbExpression left, DbExpression right, String op)
at MySql.Data.Entity.SqlGenerator.Visit(DbAndExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbAndExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SelectGenerator.Visit(DbFilterExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbFilterExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SqlGenerator.VisitInputExpression(DbExpression e, String name, TypeUsage type)
at MySql.Data.Entity.SelectGenerator.VisitInputExpressionEnsureSelect(DbExpression e, String name, TypeUsage type)
at MySql.Data.Entity.SelectGenerator.Visit(DbProjectExpression expression)
at System.Data.Entity.Core.Common.CommandTrees.DbProjectExpression.Accept[TResultType](DbExpressionVisitor`1 visitor)
at MySql.Data.Entity.SelectGenerator.GenerateSQL(DbCommandTree tree)
at MySql.Data.MySqlClient.MySqlProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree)
at System.Data.Entity.Core.Common.DbProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition..ctor(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver, BridgeDataReaderFactory bridgeDataReaderFactory, ColumnMapFactory columnMapFactory)
at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateCommandDefinition(DbProviderFactory storeProviderFactory, DbCommandTree commandTree, DbInterceptionContext interceptionContext, IDbDependencyResolver resolver)
at System.Data.Entity.Core.EntityClient.Internal.EntityProviderServices.CreateDbCommandDefinition(DbProviderManifest providerManifest, DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Common.DbProviderServices.CreateCommandDefinition(DbCommandTree commandTree, DbInterceptionContext interceptionContext)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.CreateCommandDefinition(ObjectContext context, DbQueryCommandTree tree)
at System.Data.Entity.Core.Objects.Internal.ObjectQueryExecutionPlanFactory.Prepare(ObjectContext context, DbQueryCommandTree tree, Type elementType, MergeOption mergeOption, Boolean streaming, Span span, IEnumerable`1 compiledQueryParameters, AliasGenerator aliasGenerator)
at System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClassb.<GetResults>b__a()
at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<>c__DisplayClassb.<GetResults>b__9()
at System.Data.Entity.Infrastructure.DefaultExecutionStrategy.Execute[TResult](Func`1 operation)
at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)
at System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0()
at System.Lazy`1.CreateValue()
at System.Lazy`1.LazyInitValue()
at System.Lazy`1.get_Value()
at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at MyProject.Infrastructure.DAL.Operations.UpdateUserinfo(Int32 id, Model Model) in :line 168
Is it possible that Model.LanguageIDs is null or your context has not yet been setup?
Also, do you allow for null language entries in context.languages? If anyone of those is null, you'll get this exception.
Ok, i am faced exact same problem, but found solution which might help you.
In my case LanguageIDs collection type was List<long>(unisgned int in DB), and LanguageID was int. And this type difference caused problem.
I know, that it's still a bug, and from .net point of view it's absolutely correct, but hope my post will help somebody

LINQ to Entities does not recognize the method 'System.String StringConvert(System.Nullable`1[System.Double])

I can't figure out why I'm getting this error. I have used this function successfully with previous versions of Entity Framework but I've set up a new project using EF6 and it's not cooperating.
using System.Data;
using System.Data.Objects.SqlClient;
e.Result = from n in MyDB.tblBulletins
where n.AnncStart <= DateTime.Now && n.AnncEnd > DateTime.Now && n.Approved == true
orderby n.AnncStart descending, n.AnncDate descending
select new
{
n.RecID,
AnncTitle = n.AnncTitle + " <a href='bulletinAdd.aspx?ID=" + SqlFunctions.StringConvert((double)n.RecID).Trim() + "'><Edit></a>",
AnncText = (n.AnncImg == null ? n.AnncText : "<a href='images/bulletin/" + n.AnncImg + "'><img src='images/bulletin/" + n.AnncImg + "' class='stickyphoto' alt='Click for larger image'/></a>" + n.AnncText),
Email = (n.Email == null ? "" : "<br/><a href='mailto:" + n.Email + "'>" + n.Email + "</a>"),
n.AnncType,
n.AnncDate,
n.AnncEnd,
n.v_EmpBasicInfo.Name
};
When I run this I get
LINQ to Entities does not recognize the method 'System.String StringConvert(System.Nullable`1[System.Double])' method, and this method cannot be translated into a store expression.
n.RecID is an int primary key on the table in a SQL database (SQL Server Standard Edition)
All I can seem to find through searches is people recommending StringConvert instead of ToString
ADDITION - Stack Trace:
[NotSupportedException: LINQ to Entities does not recognize the method 'System.String StringConvert(System.Nullable`1[System.Double])' method, and this method cannot be translated into a store expression.]
System.Data.Entity.Core.Objects.ELinq.DefaultTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) +194
System.Data.Entity.Core.Objects.ELinq.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) +976
System.Data.Entity.Core.Objects.ELinq.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq) +88
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) +148
System.Data.Entity.Core.Objects.ELinq.BinaryTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression linq) +122
System.Data.Entity.Core.Objects.ELinq.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq) +88
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) +148
System.Data.Entity.Core.Objects.ELinq.BinaryTranslator.TypedTranslate(ExpressionConverter parent, BinaryExpression linq) +87
System.Data.Entity.Core.Objects.ELinq.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq) +88
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) +148
System.Data.Entity.Core.Objects.ELinq.NewTranslator.TypedTranslate(ExpressionConverter parent, NewExpression linq) +520
System.Data.Entity.Core.Objects.ELinq.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq) +88
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) +148
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input) +168
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateLambda(LambdaExpression lambda, DbExpression input, DbExpressionBinding& binding) +160
System.Data.Entity.Core.Objects.ELinq.OneLambdaTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, DbExpression& source, DbExpressionBinding& sourceBinding, DbExpression& lambda) +168
System.Data.Entity.Core.Objects.ELinq.SelectTranslator.Translate(ExpressionConverter parent, MethodCallExpression call) +70
System.Data.Entity.Core.Objects.ELinq.SequenceMethodTranslator.Translate(ExpressionConverter parent, MethodCallExpression call, SequenceMethod sequenceMethod) +47
System.Data.Entity.Core.Objects.ELinq.MethodCallTranslator.TypedTranslate(ExpressionConverter parent, MethodCallExpression linq) +141
System.Data.Entity.Core.Objects.ELinq.TypedTranslator`1.Translate(ExpressionConverter parent, Expression linq) +88
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.TranslateExpression(Expression linq) +148
System.Data.Entity.Core.Objects.ELinq.ExpressionConverter.Convert() +50
System.Data.Entity.Core.Objects.ELinq.ELinqQueryState.GetExecutionPlan(Nullable`1 forMergeOption) +563
System.Data.Entity.Core.Objects.<>c__DisplayClassb.<GetResults>b__a() +83
System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction(Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) +499
System.Data.Entity.Core.Objects.<>c__DisplayClassb.<GetResults>b__9() +271
System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(Func`1 operation) +251
System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) +600
System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0() +89
System.Lazy`1.CreateValue() +416
System.Lazy`1.LazyInitValue() +152
System.Lazy`1.get_Value() +75
System.Data.Entity.Internal.LazyEnumerator`1.MoveNext() +40
System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +381
System.Linq.Enumerable.ToList(IEnumerable`1 source) +58
[TargetInvocationException: Exception has been thrown by the target of an invocation.]
System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) +0
System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) +92
System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +108
System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters) +19
System.Web.UI.WebControls.QueryableDataSourceHelper.ToList(IQueryable query, Type dataObjectType) +225
System.Web.UI.WebControls.LinqDataSourceView.ExecuteSelect(DataSourceSelectArguments arguments) +549
System.Web.UI.WebControls.Repeater.GetData() +55
System.Web.UI.WebControls.Repeater.CreateControlHierarchy(Boolean useDataSource) +89
System.Web.UI.WebControls.Repeater.OnDataBinding(EventArgs e) +61
System.Web.UI.WebControls.Repeater.DataBind() +105
System.Web.UI.WebControls.Repeater.EnsureDataBound() +49
System.Web.UI.WebControls.Repeater.OnPreRender(EventArgs e) +15
System.Web.UI.Control.PreRenderRecursiveInternal() +83
System.Web.UI.Control.PreRenderRecursiveInternal() +168
System.Web.UI.Control.PreRenderRecursiveInternal() +168
System.Web.UI.Control.PreRenderRecursiveInternal() +168
System.Web.UI.Control.PreRenderRecursiveInternal() +168
System.Web.UI.Control.PreRenderRecursiveInternal() +168
System.Web.UI.Control.PreRenderRecursiveInternal() +168
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +974
I had the same problem and realized that I was using the wrong type of SqlFunctions. Make sure that you referenced the correct namespace:
using System.Data.Entity.SqlServer;
and not:
using System.Data.Objects.SqlClient;
You don't have to convert it to string, string concatenation will take care of that.
AnncTitle = n.AnncTitle + " <a href='bulletinAdd.aspx?ID=" + n.RecID + "'><Edit></a>",
You don't have to call ToString as well.

LINQ-NHibernate - Selecting only a few fields (including a Collection) for a complex object

I'm using Fluent NHibernate in one of my projects (and ASP.NET MVC application), with LINQ to query to data (using the LINQ to NHibernate libraries).
The objet names are changed to protect the innocent.
Let's say I have the following classes Foo, Bar, Baz, and their appropriate tables in the database (MySQL).
Foo has a many-to-many relationship with both Bar (table "FooBar") and Baz (table "FooBaz"), defined in the Fluent mappings. As such, the class interface is defined as follows:
public class Foo {
public virtual int id { get; set; }
public virtual string name { get; set; }
public virtual string email { get; set; }
public virtual IList<Bar> bars { get; set; }
public virtual IList<Baz> bazes { get; set; }
}
This is a pretty standard class. We can see that a Foo object will have a list of bars and bazes.
The problem comes when trying to do a LINQ query.
If I do a simple query like this, it works fine (the where clause is unimportant) :
var foos = from foo in session.Linq<Foo>()
where email.equals("foo#bar.com")
select foo;
IList<Foo> listFoos = foos.ToList();
This will return a list of Foos, with all the fields populated (id, name, email, bars, bazes). log4net shows that NHibernate performs separate queries for the collections.
The problem arises when I want to load only some fields. For example, I might want to load only the bars in the query, but not the bazes.
This query compiles, but produces an error at runtime:
var foos = from foo in session.Linq<Foo>()
where email.equals("foo#bar.com")
select new Foo()
{
id = foo.id,
name = foo.name,
email = foo.email,
bars = foo.bars
};
IList<Foo> listFoos = foos.ToList();
The error I get is something along the lines of an array index out of bounds exception. The stack trace shows some methods names relating the collection handling on LINQ-NHibernate's side, but nothing else. The query reported by log4net shows no sign of a query on bars, which means than an error was caught before it had the time to perform the query to select the bars.
Did anyone else had this kind of problem before? How did you solve it? I don't want to have to select all the objects everytime I open a web page in my application!
Thank you!
Edit: here is the stacktrace, as requested.
System.IndexOutOfRangeException: L'index se trouve en dehors des limites du tableau. (read: "Index is out of bounds for the array.")
[IndexOutOfRangeException: L'index se trouve en dehors des limites du tableau.]
NHibernate.Transform.TypeSafeConstructorMemberInitResultTransformer.InvokeMemberInitExpression(MemberInitExpression expression, Object[] args, Int32& argumentCount) +404
NHibernate.Transform.TypeSafeConstructorMemberInitResultTransformer.TransformTuple(Object[] tuple, String[] aliases) +150
[QueryException: could not instantiate: Foo]
NHibernate.Transform.TypeSafeConstructorMemberInitResultTransformer.TransformTuple(Object[] tuple, String[] aliases) +265
NHibernate.Loader.Criteria.CriteriaLoader.GetResultColumnOrRow(Object[] row, IResultTransformer resultTransformer, IDataReader rs, ISessionImplementor session) +171
NHibernate.Loader.Loader.GetRowFromResultSet(IDataReader resultSet, ISessionImplementor session, QueryParameters queryParameters, LockMode[] lockModeArray, EntityKey optionalObjectKey, IList hydratedObjects, EntityKey[] keys, Boolean returnProxies) +330
NHibernate.Loader.Loader.DoQuery(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +704
NHibernate.Loader.Loader.DoQueryAndInitializeNonLazyCollections(ISessionImplementor session, QueryParameters queryParameters, Boolean returnProxies) +70
NHibernate.Loader.Loader.DoList(ISessionImplementor session, QueryParameters queryParameters) +111
NHibernate.Loader.Loader.ListIgnoreQueryCache(ISessionImplementor session, QueryParameters queryParameters) +18
NHibernate.Loader.Loader.List(ISessionImplementor session, QueryParameters queryParameters, ISet`1 querySpaces, IType[] resultTypes) +79
NHibernate.Impl.SessionImpl.List(CriteriaImpl criteria, IList results) +407
NHibernate.Impl.CriteriaImpl.List(IList results) +41
NHibernate.Impl.CriteriaImpl.List() +35
NHibernate.Linq.<GetEnumerator>d__0.MoveNext() +71
System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +7665172
System.Linq.Enumerable.ToList(IEnumerable`1 source) +61
FooRepository.List(Int32 count) in C:\...\FooRepository.cs:38
FooController.List() in C:\...\FooController.cs:30
lambda_method(ExecutionScope , ControllerBase , Object[] ) +39
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +17
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +178
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +24
System.Web.Mvc.<>c__DisplayClassa.<InvokeActionMethodWithFilters>b__7() +52
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation) +254
System.Web.Mvc.<>c__DisplayClassc.<InvokeActionMethodWithFilters>b__9() +19
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodWithFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +192
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +399
System.Web.Mvc.Controller.ExecuteCore() +126
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +27
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +7
System.Web.Mvc.MvcHandler.ProcessRequest(HttpContextBase httpContext) +151
System.Web.Mvc.MvcHandler.ProcessRequest(HttpContext httpContext) +57
System.Web.Mvc.MvcHandler.System.Web.IHttpHandler.ProcessRequest(HttpContext httpContext) +7
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +181
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
A couple of suggestions...
First, NHibernate defaults to lazy loading, so there may not even be a need to do the more "efficient" query you're attempting.
Second, the following code does not quite do what your example code does - it creates a list of anonymous types called miniFoos that contain a subset of the fields in Foo. But the net effect is similar to what you seem to be attempting. It also uses what I believe is called LINQ method syntax.
I tested this in on an entity in my own application, which also has an IList property, and it does work (though I should note that I'm currently using Eager loading). I just cut and pasted the working code and substituted your example's names.
using( var session = sessionFactory.OpenSession() )
{
session.BeginTransaction();
var foos =
session.CreateCriteria(typeof(Foo))
.List<Foo>();
var miniFoos =
foos.Select(f => new { f.email, f.bars })
.Where(f => f.email.Equals("foo#bar.com)
.ToList();
session.Close();
}
I tried answering this already, but am not happy with it.
The more I think about your question, the more it seems like you are trying to do your own version of Lazy Loading, which NHibernate handles pretty well on it's own, in my experience.
I know (from a comment) that you switched to Eager Loading because you were not keeping a session open. I think it would be more useful for you in the long run if you focused on that angle.
If I've misunderstood, perhaps you could edit the question to explain why you think you need to handle it yourself?
I could manage to project not the whole collection but its fields
...
Select(a => new Forum {
Id = a.Id,
Name = a.Name,
CategoryName = a.Categories.Select(b => b.Name).First()
})
CategoryName is an computed filed in the Forum Entity
which does not have any mapping with DB
In result I got a small projection of the huge Forum Entity and a possibility to sort on the field.
Hope that it will help somebody.
i think you can solve your problem by defining the result transformer and the result set names, if in some way you can access the Criteria that being generated you can avoid anonymous object.
the problem is that the property names and column names are not the same, and when using projection nhibernate/linq to nhibernate does not check what the column name and the property name. so if u'll define them by yourself in the result properties (i think its called result set) in the criteria before you execute the query it should work.
it's pretty simple, give it a try

Categories