Here is the console app VB.NET code:
Imports System.Data.Entity
Imports System.Linq
Imports System.Configuration
Module Module1
Sub Main()
Using db = New BloggingContext()
Console.Write("Enter a name for a new Blog: ")
Dim name = Console.ReadLine()
Dim blogt As New Blog()
With blogt
.Name = name
End With
db.Blogs.Add(blogt)
db.SaveChanges()
Dim query = From b In db.Blogs
Order By b.Name
Console.WriteLine("All blogs in the database:")
For Each item In query
Console.WriteLine(item.Name)
Next
Console.WriteLine("Press any key to exit...")
Console.ReadKey()
End Using
End Sub
Public Class Blog
Public Property BlogId() As Integer
Public Property Name() As String
End Class
Public Class BloggingContext
Inherits DbContext
Public Sub New()
MyBase.New("dbConnString")
End Sub
Public Blogs As DbSet(Of Blog)
End Class
End Module
My error points to this line in Main() 'db.Blogs.Add(blogt)' stating "System.NullReferenceException: Object reference not set to an instance of an object."
When I mouse over db.Blogs.Add(blogt), it tells me that db.Blogs is nothing. I converted the same code into C# and it works perfectly:
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity;
namespace CodeFirstNewDatabaseSample
{
class Program
{
static void Main(string[] args)
{
using (var db = new BloggingContext())
{
// Create and save a new Blog
Console.Write("Enter a name for a new Blog: ");
var name = Console.ReadLine();
var blog = new Blog { Name = name };
db.Blogs.Add(blog);
db.SaveChanges();
// Display all Blogs from the database
var query = from b in db.Blogs
orderby b.Name
select b;
Console.WriteLine("All blogs in the database:");
foreach (var item in query)
{
Console.WriteLine(item.Name);
}
Console.WriteLine("Press any key to exit...");
Console.ReadKey();
}
}
}
public class Blog
{
public int BlogId { get; set; }
public string Name { get; set; }
public virtual List<Post> Posts { get; set; }
}
public class Post
{
public int PostId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public virtual Blog Blog { get; set; }
}
public class BloggingContext : DbContext
{
public BloggingContext()
: base("dbConnString")
{
//Database.SetInitializer<BloggingContext>(new CreateDatabaseIfNotExists<BloggingContext>());
}
public DbSet<Blog> Blogs { get; set; }
public DbSet<Post> Posts { get; set; }
}
}
Not sure what's missing. I've read all the other EF posts regarding the NullReferenceException error when attempting to SaveChanges, but none have resolved the issue for me yet. Where's Waldo in this?
Blogs is not a property in the VB code, it should be:
Public Property Blogs As DbSet(Of Blog)
Without "Property" it's just a member variable, so it's not automatically initialized by the DbContext.
Related
I have this entity:
public class Genres
{
public int Id { get; set; }
[Required(ErrorMessage ="the field {0} is required")]
[StringLength(50)]
[FirstLetterUpperCase]
public string Name { get; set; }
}
And this DTO or model:
public class GenresDTO
{
public int Id { get; set; }
public string Name { get; set; }
}
I have initiated my mapper like this:
public class AutoMapperClass : Profile
{
public AutoMapperClass()
{
generateMapper();
}
private void generateMapper()
{
CreateMap<GenresDTO, Genres>().ReverseMap();
CreateMap<GenresCreationDTO, Genres>();
}
}
I have also written this part of code in my program.cs :
builder.Services.AddAutoMapper(typeof(IStartup));
I am using .NET 6 and Visual Studio, and when I run my project, I get an error that is mentioned in the title and its related to this section :
public async Task<ActionResult<List<GenresDTO>>> Get()
{
var genres = await dbContext.Genres.ToListAsync();
return mapper.Map<List<GenresDTO>>(genres);
}
which is in my Controller file, and I initiated the mapper like this :
private readonly ILogger<GenresController> ilogger;
private readonly ApplicationDBContext dbContext;
private readonly IMapper mapper;
public GenresController(ILogger<GenresController> ilogger,
ApplicationDBContext dbContext , IMapper mapper)
{
this.ilogger = ilogger;
this.dbContext = dbContext;
this.mapper = mapper;
}
Should be probably typeof(Program) in registration (assuming that you are using .Net6 where we have only Program.cs)
builder.Services.AddAutoMapper(typeof(Program))
If you have multiple projects in solution,then value used there should be a file in the assembly in which the mapping configuration resides.
Im trying to use a Class in a WCF service. When im calling the
u.attributeChanges.Add(a);
i get:
"Object reference not set to an instance of an object"
If create the classes in the client application it's working.
UpdateChanges Class
[DataContract]
public class UpdateChanges
{
private void Initialize()
{
this.attributeChanges = new List<AttributeChanges>();
}
public UpdateChanges()
{
this.Initialize();
}
[DataMember]
public string objectGuid { get; set; }
[DataMember]
public Utilities.ObjectTypes objectType { get; set; }
[DataMember]
public Utilities.ChangeType changeType{ get; set; }
[DataMember]
public List<AttributeChanges> attributeChanges { get; set; }
[OnDeserializing]
public void OnDeserializing(StreamingContext ctx)
{
this.Initialize();
}
}
AttributeChanges class
[DataContract]
public class AttributeChanges
{
[DataMember]
public string attributeName { get; set; }
[DataMember]
public string attributeValue { get; set; }
}
Client Code:
Service.DirsyncServiceClient proxyClient;
proxyClient = Utilities.GetProxy("http://192.168.1.45/vDir/Service.svc");
Service.UpdateChanges u = new Service.UpdateChanges();
Service.AttributeChanges a = new Service.AttributeChanges();
a.attributeName = "Attribute1";
a.attributeValue = "Value1";
u.attributeChanges.Add(a);
proxyClient.SaveObject(u);
Anyonw know how to solve this?
You're using a generated client code.
The problem is that the client generates this code on base of the WSDL xlm. The code in the CTOR doesn't generated in the client because the client can't be aware of this code.
You have a few options-
1. Use a shared DLL with the data contract instead of generating it via a web reference.
2. Implement it yourself in a 'partial' class.
I'm learning WCF, and tried to make a small service that exposes a Project and its tasks (the standard Entity Framework hello world).
The class structure is the following:
public class Project
{
public int ProjectId { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime CreationDate { get; set; }
public virtual ICollection<Task> Tasks { get; set; }
}
public class Task
{
public int TaskId { get; set; }
public string Title { get; set; }
public virtual Project RelatedProject { get; set; }
}
The DB context comes after:
public class ProjectContext : DbContext
{
public DbSet<Project> Projects { get; set; }
public DbSet<Task> Tasks { get; set; }
}
Finally, the service endpoint:
public IEnumerable<Project> getProjects()
{
ProjectContext p = new ProjectContext();
return p.Projects.AsEnumerable();
}
The problem is that this model will throw a System.ServiceModel.CommunicationException, but, If I remove the virtual properties from the model, It would work, but I would loose the entity framework links between Project and Task.
Anyone with a similar setup?
I banged my head against the wall several hours with this one. After extensive debugging, google gave the answer and I feel right to post it here since this was the first result I got in google.
Add this class on top of your [ServiceContract] interface declaration (typically IProjectService.cs
public class ApplyDataContractResolverAttribute : Attribute, IOperationBehavior
{
public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
{
}
public void ApplyClientBehavior(OperationDescription description, System.ServiceModel.Dispatcher.ClientOperation proxy)
{
var dataContractSerializerOperationBehavior =
description.Behaviors.Find<DataContractSerializerOperationBehavior>();
dataContractSerializerOperationBehavior.DataContractResolver =
new ProxyDataContractResolver();
}
public void ApplyDispatchBehavior(OperationDescription description, System.ServiceModel.Dispatcher.DispatchOperation dispatch)
{
var dataContractSerializerOperationBehavior =
description.Behaviors.Find<DataContractSerializerOperationBehavior>();
dataContractSerializerOperationBehavior.DataContractResolver =
new ProxyDataContractResolver();
}
public void Validate(OperationDescription description)
{
// Do validation.
}
}
Requirements are
using System.ServiceModel.Description;
using System.Data.Objects;
using System.ServiceModel.Channels;
Then under the [OperationContract] keyword add [ApplyDataContractResolver] keyword and you are set!
Big thanks to http://blog.rsuter.com/?p=286
For sending data trough WCF you should disable lazy loading (dataContext.ContextOptions.LazyLoadingEnabled = false;).
To be sure the data you want is loaded you need to use eager loading ( trough the Include method).
You need to change your function to:
public IEnumerable<Project> getProjects()
{
ProjectContext p = new ProjectContext();
p.ContextOptions.LazyLoadingEnabled = false;
return p.Projects.Include("Tasks").AsEnumerable();
}
I am new to WCF services. I was asked to manually create a WCF service. I did the following:
Created a new project Console App.
Created a class called Evaluation
Created an interface called IEvaluatorService
Created a class EvaluationService implementing the interface IEvaluatorService
I need to use the following address: http://localhost:8000/Evaluations then test my service via WcfTestClient. I am not sure what to do next. Code below.
Thanks in advance for any help!
namespace Evaluations
{
[ServiceContract]
interface IEvaluatorService
{
[OperationContract(Name="AddEvaluation")]
int Add(string user, string content);
[OperationContract(Name="RemoveEvaluation")]
void Remove([MessageParameter(Name="existingID")] int id);
[OperationContract(Name="GetAllEvaluations")]
Evaluation[] GetAll();
[OperationContract(Name="GetEvaluation")]
Evaluation Get(int id);
[OperationContract(Name="GetAllEvaluationsFrom")]
Evaluation[] GetAll([MessageParameter(Name = "username")] string submitter);
}
}
namespace Evaluations
{
class EvaluationService : IEvaluatorService
{
List<Evaluation> myList = new List<Evaluation>();
static int count = 0;
public int Add(string user, string content)
{
Evaluation eval = new Evaluation()
{
UniqueID = count++,
Submitter = user,
SubmissionTime = DateTime.Now,
Text = content
};
myList.Add(eval);
return eval.UniqueID;
}
public void Remove(int id)
{
myList.RemoveAt(id);
}
public Evaluation[] GetAll()
{
return myList.ToArray<Evaluation>();
}
public Evaluation Get(int id)
{
throw new NotImplementedException();
}
public Evaluation[] GetAll(string submitter)
{
throw new NotImplementedException();
}
}
}
namespace Evaluations
{
[DataContract]
class Evaluation
{
[DataMember]
public string Submitter { get; set; }
[DataMember]
public int UniqueID { get; set; }
[DataMember]
public DateTime SubmissionTime { get; set; }
[DataMember]
public string Text { get; set; }
}
}
The easiest thing to do is...
go into Visual Studio
right click on your project
select Add New
choose WCF Service
See what code Visual Studio added and follow that pattern for your service.
I want to design a orm tool for my daily work, but I'm always worry about the mapping of foreign key.
Here's part of my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace OrmTool
{
[AttributeUsage(AttributeTargets.Property)]
public class ColumnAttribute:Attribute
{
public string Name { get; set; }
public SqlDbType DataType { get; set; }
public bool IsPk { get; set; }
}
[AttributeUsage(AttributeTargets.Class,AllowMultiple=false,Inherited=false)]
public class TableAttribute:Attribute
{
public string TableName { get; set; }
public string Description { get; set; }
}
[AttributeUsage(AttributeTargets.Property)]
public class ReferencesAttribute : ColumnAttribut
{
public Type Host { get; set; }
public string HostPkName{get;set;}
}
}
I want to use Attribute to get the metadata of Entity ,then mapping them,but i think it's really hard to get it done;
public class DbUtility
{
private static readonly string CONNSTR = ConfigurationManager.ConnectionStrings["connstr"].ConnectionString;
private static readonly Type TableType = typeof(TableAttribute);
private static readonly Type ColumnType = typeof(ColumnAttribute);
private static readonly Type ReferenceType = typeof(ReferencesAttribute);
private static IList<TEntity> EntityListGenerator<TEntity>(string tableName,PropertyInfo[] props,params SqlParameter[] paras) {
return null;
}
private static SqlCommand PrepareCommand(string sql,SqlConnection conn,params SqlParameter[] paras) {
SqlCommand cmd = new SqlCommand();
cmd.CommandText = sql;
cmd.Connection = conn;
if (paras != null)
cmd.Parameters.AddRange(paras);
conn.Open();
return cmd;
}
}
I don't know how to do the next step, if every Entity has it's own foreign key,how do I get the return result ? If the Entity like this:
[Table(Name="ArtBook")]
public class ArtBook{
[column(Name="id",IsPk=true,DataType=SqlDbType.Int)]
public int Id{get;set;}
[References(Name="ISBNId",DataType=SqlDataType.Int,Host=typeof(ISBN),HostPkName="Id")]
public ISBN BookISBN{get;set;}
public .....more properties.
}
public class ISBN{
public int Id{get;set;}
public bool IsNative{get;set;}
}
If I read all ArtBooks from database and when I get a ReferencesAttribute how do I set the value of BookISBN?
in method EntityListGenerator ,I try to make a recursion that get mapping,but i don't know how to do next ,for each foreign key i'll read data from database? or get all foreign then mapping? those all too bad.