|
OK, now you changed the original post so that there are order. Same problem. Create records for a single table at a time then save the changes.
Create the Companies first and save them, then add Orders and save them.
|
|
|
|
|
could you please help me?
If I first save company first it will be as below
using (var dbCtx = new CustomerManagerContext())
{
dbCtx.Companies.Add(company1);
dbCtx.SaveChanges();
}
company1.Customers.Add(customer1);
company1.Customers.Add(customer2);
customer1.Orders.Add(order1);
customer2.Orders.Add(order2);
how do I now save customer1, customer2 and order1 and order2 using the context?
|
|
|
|
|
I do have a requirement for you when writing code: USE YOUR BRAIN!
Serisously? What's preventing you from putting the other creation objects in the same "using" context? NOTHING! You can call SaveChanges multiple times before disposing the CustomerManagerContext.
So, create your Customers, SaveChanges. Create your Companies, SaveChanges. Create your Orders, SaveChanges, ...
See a pattern there?
|
|
|
|
|
Ok. I did as per you mentioned but I get below error now
using (var dbCtx = new CustomerManagerContext())
{
dbCtx.Customers.Add(customer1);
dbCtx.SaveChanges();
dbCtx.Customers.Add(customer2);
dbCtx.SaveChanges();
dbCtx.Companies.Add(company1);
dbCtx.SaveChanges();
dbCtx.Orders.Add(order1);
dbCtx.SaveChanges();
dbCtx.Orders.Add(order2);
dbCtx.SaveChanges();
}
Entities in 'CustomerManagerContext.Customers' participate in the 'Customer_Companies' relationship. 0 related 'Customer_Companies_Target' were found. 1 'Customer_Companies_Target' is expected.
this is because I have below method
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>().
HasMany(c => c.Companies).
WithMany(p => p.Customers).
Map(
m =>
{
m.MapLeftKey("CustomerId");
m.MapRightKey("CompanyId");
m.ToTable("CustomerCompany");
});
modelBuilder.Entity<Company>().HasRequired(c => c.Customers).WithMany().WillCascadeOnDelete(false);
modelBuilder.Entity<Customer>().HasRequired(c => c.Companies).WithMany().WillCascadeOnDelete(false);
base.OnModelCreating(modelBuilder);
}
sorry still learning entity framework.
|
|
|
|
|
Please remove that OnModelCreating. It's pretty broken; it would require that a customer exist before a company does, and that a company exist before a customer does....
|
|
|
|
|
Okay, you have a little work to do on this. even when using POCOs, you need to keep the shape of the database and the limitations of SQL (like field values in tables) in mind. You still use foreign keys to map to complex types, and you cannot insert values into a SQL field that it does not recognize as a native type.
I'm assuming your context class looks like:
public class MyContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
public DbSet<Company> Companies { get; set; }
public DbSet<Order> Orders { get; set; }
}
You have a M:M mapping for customers to companies, and and 1:M for customers and orders (I'm guessing). without seeing the Order class, it looks like our base structure has an few inherent flaws, and will not be able to normalize or even perform proper data access at the moment.
Here's the obvious changes:
public class Company
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] [Display(AutoGenerateField = false)]
public int CompanyId { get; set; }
[StringLength(50)]
public string Name { get; set; }
[StringLength(200)]
public string Address { get; set; }
[StringLength(500)]
public string Email { get; set; }
[StringLength(1000)]
public string Phone { get; set; }
[StringLength(50)]
public string City { get; set; }
public State State { get; set; }
public int StateId { get; set; }
public int Zip { get; set; }
public virtual ICollection Orders{ get; set; }
}
public class Customer
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] [Display(AutoGenerateField = false)]
public int CustomerId { get; set; }
[StringLength(50)]
public string FirstName { get; set; }
[StringLength(50)]
public string LastName { get; set; }
[StringLength(100)]
public string Email { get; set; }
[StringLength(1000)]
public string Address { get; set; }
[StringLength(50)]
public string City { get; set; }
public int Zip { get; set; }
[Display(AutoGenerateField = false), ForeignKey("State")]
public int StateId { get; set; }
public virtual State State { get; set; }
public virtual ICollection Orders{ get; set; }
public string Gender { get; set; }
Okay, now that the changes are made to those classes, let's look at a possible Orders class. I'll just add the fields to wire the M:M up, I don't know what other fields you have in there. This is assuming that One Customer can have Many Orders, and One Company can have Many Orders, but each Order has only One Customer and only One Company.
public class Order
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] [Display(AutoGenerateField = false)]
public int Id { get; set; }
[Display(AutoGenerateField = false), ForeignKey("Customer")]
public int CustomerId { get; set; }
[Display(AutoGenerateField = false), ForeignKey("Company")]
public int CompanyId { get; set; }
public virtual Customer Customer { get; set; }
public virtual Company Company { get; set; }
public Order(){}
public Order(Customer customer, Company company)
{
CustomerId = customer.CustomerId;
CompanyId = company.CompanyId;
}
}
My sample has a parametrized constructor, but that's optional. If you do include one, though, always include a default constructor.
Now let's swing back to the Context class and implement an Update method.
public class MyContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
public DbSet<Company> Companies { get; set; }
public DbSet<Order> Orders { get; set; }
public bool UpdateOrder(Order order)
{
if(Orders.Any(x => x.Id == order.Id))
this.Entry(order).State = EntityState.Modified;
else
Orders.Add(order);
return this.SaveChanges() != 0;
}
public bool UpdateCompany(Company company)
{
if(Companies.Any(x => x.CompanyId == company.CompanyId))
this.Entry(company).State = EntityState.Modified;
else
Companies.Add(company);
return this.SaveChanges() != 0;
}
public bool UpdateCustomer(Customer customer)
{
if(Customers.Any(x => x.CustomerId == customer.CustomerId))
this.Entry(customer).State = EntityState.Modified;
else
Customers.Add(customer);
return this.SaveChanges() != 0;
}
public bool DeleteOrder(Order order)
{
if(Orders.Any(x => x.Id == order.Id))
{
Orders.Remove(order);
return this.SaveChanges() != 0;
}
return false;
}
}
Then just create objects and add them via context.Update().
modified 25-Jun-14 10:11am.
|
|
|
|
|
Hi, thanks for the detailed explaination. In my case, a company can have many customer and a customer can belong to many companies. only customers will have order. Sorry to call this "order". It should actually be called "Job". Would I require making any changes to what you have described above for my situation?
|
|
|
|
|
Hi guys,
I'm new to VB6 and also MSMQ. I went through a lot of tutorials online but seems like there is no solution for my question.
I managed to sending from C# to C# or VB6 to VB6 but not from VB6 to C# or vice versa. So I wonder is it a way to do that or there is no way to do this kind of communication.
For example: I want to send this to MSMQ
Dim PropBag As PropertyBag
Set PropBag = New PropertyBag
PropBag.WriteProperty "Customer", "Bob"
PropBag.WriteProperty "Product", "MoeHairSuit"
PropBag.WriteProperty "Quantity", 4
and get the details in C#, there is "Invalid character in the given encoding. Line 1, position 1." error when I use XmlMessageFormatter
Message mes = mq.Receive(new TimeSpan(0, 0, 3));
mes.Formatter = new XmlMessageFormatter(new String[] { "System.String,mscorlib" });
result = mes.Body.ToString();
I also tried to read from the stream but it come out with a weird symbol in my string. Below is the code and this is the output "늓\0\0\b\b휖ꭑ(\0customer\0Bob\0\b\a劑틠4\0product\v\0MoeHairSuit\b調⫳ᄂ.quantity\0"
Message mes;
mes = mq.Receive(new TimeSpan(0, 0, 3));
mes.BodyStream.Position = 0;
byte[] b = new byte[mes.BodyStream.Length];
mes.BodyStream.Read(b, 0, (int)mes.BodyStream.Length);
UnicodeEncoding uniCoder = new UnicodeEncoding();
result = uniCoder.GetString(b);
I get this exception "Cannot deserialize the message passed as an argument. Cannot recognize the serialization format." when using ActiveXMessageFormatter like below
mes = mq.Receive(new TimeSpan(0, 0, 3));
mes.Formatter = new ActiveXMessageFormatter();
result = mes.Body.ToString();
Do you guys have any idea how to do that?
Thanks in advanced
modified 25-Jun-14 5:32am.
|
|
|
|
|
I haven't done any work in VB6 in quite a long time, but I would suspect that you can't use a PropertyBag to do this.
Why are you using VB6 at all since it's been dead for quite a while now?
|
|
|
|
|
I have programs which are in VB6 and communicate using MSMQ. I am trying to migrate the receiver into C# and the sender remains as VB6 cause a lot of my clients are using the VB6 program. So the problem is how can I extract the data send by VB6 which is in propertyBag format using C#?
|
|
|
|
|
After a bit of research it looks like you're hosed. The only viable solution I can find is to create a COM DLL in VB6 that deserializes the object from the MSMQ and then pass the data back to C# through the COM interface.
|
|
|
|
|
Thanks @Dave for your time
|
|
|
|
|
The data sent by VB6 are not at all xml formatted, nor do they use unicode.
Well, you already receive a byte array. Now look into it, compare that with the data you knew you sent from VB6, and do some reverse-engineering. That's a bad job, but it can work.
|
|
|
|
|
Thanks @Bernhard Hiller. The byte array received are same with the one received in VB6 but only VB6 can understand them. C# gave me some weird symbols. In VB6, I just need to assign the byte array back to propertyBag.contents then propertyBag will take care everything for me. Tried to search in internet but cannot get any example on the reverse-engineering. It is a time consuming process so want to check whether there is another easier way to do this
|
|
|
|
|
Hi,
I have to write code logic in Inno setup project and want to place all code logic in a separate class. Is it possible in Inno setup.
|
|
|
|
|
This has nothing to do with C#. Try the InnoSetup support forums as they are the best placed people to give you an answer.
|
|
|
|
|
Yes right Pete O'Hanlon..thanx
|
|
|
|
|
Hi,
I would like to ask what's the best way to create and manupulate Microsoft Excel files in C#?
Thanks,
Jassim
Technology News @ www.JassimRahma.com
|
|
|
|
|
|
Try one of these, particularly if you're writing a program which will run unattended:
They're all free and open-source, and none of them need Excel installed on the computer.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Hello! You can use simple code to do, without external tools as Microsoft suggest. To initiate the excel, follow the code
<pre lang="c#">
using sExcel = Microsoft.Office.Interop.Excel;
using Microsoft.Office.Interop.Excel;
sExcel.Application excel = new sExcel.Application();
excel.ScreenUpdating = false;
excel.Visible = false;
excel.DisplayAlerts = false;
excel.AutomationSecurity = Microsoft.Office.Core.MsoAutomationSecurity.msoAutomationSecurityLow;
Workbook wb = excel.Workbooks.Add();
Worksheet ws = excel.Worksheets[1];
ws.Name = "ws";
Lucas Rafael Leandro Silva
|
|
|
|
|
|
I'm trying to get my web application to reload a DbContext cache after initialization to introduce new entities (if available, as introduced via MEF) into the context model. Currently the context populates via an OnModelCreating overload.
public class MyContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var models = DependencyResolver.Current.GetServices(typeof(IModel));
foreach (var model in models)
{
var entityMethod = typeof(DbModelBuilder).GetMethod("Entity");
entityMethod.MakeGenericMethod(model.GetType())
.Invoke(modelBuilder, new object[] { });
}
}
I use a custom initializer that will add entities as appropriate on initilization ( I'm working on an archive for entity removal, but that's another topic).
My issue is this: I would like to dynamically load modules, have the context pick-up the IModel objects immediately and make them available for use. Does anyone know of a hook that will allow me to re-initialize the context and clear the cache without a complete application restart?
Note: I don't want to disable the cache completely, as this will not be an overly common task and it does offer more benefit than this functionality is worth.
|
|
|
|
|
You picked a very odd place to put the cache initialization code. You also don't mention what kind of application this is, Windows Forms, WPF, or ASP.NET.
It would be better if you implemented your own caching scheme so you have more flexibility on when it initializes, what it loads and how and what you clear. Your code implies that you're relying on a context that is created once during application startup, is never disposed and is basically pre-loading the entire database into memory. That really doesn't scale well!
I did something similar in a web app I'm working on now. I created my own custom caching scheme. It's just a single interface and a couple of classes really, and based all of my controllers and service layers on base implementations of it.
Data items that are used frequently, but rarely ever change are cached only when they are initially requested and dumped and reloaded at various points in the code when required, depending on what edit operations are taking place. I can also either dump an entire table of cached data or just a single item and replace it.
|
|
|
|
|
The DbContext lives in an MVC application, but from my understanding that should be immaterial as it's specifically an EF implementation and not an MVC one. The context itself is wrapped by a separate UnitOfWork object that is injected into my controllers, and it explicitly disposes each context instance (per request). The UoW abstracts the data source so that I can use the same controller-base with multiple sorts of data sources (XML, Web services, LDAP, etc).
I like your thought of a custom cache control; I've been so wrapped up in the details of the Entity Framework that such a clear solution hadn't crossed my mind, sadly enough. Forests and trees.
I use that as a fallback if I cannot determine another implementation using the framework itself. Thank you for the perspective!
|
|
|
|