Гость
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Entitity Framework удаление объектов many-to-many / 5 сообщений из 5, страница 1 из 1
11.07.2011, 09:56
    #37345605
mar55555
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entitity Framework удаление объектов many-to-many
для регистрации пользователей использую стандартный membership. нужно удалять пользователей. не получается через entity framework. точнее работает, но только вот так

string message = df.CanDeleteUserById(newUser.UserId).FirstOrDefault(); //проверяет нет ли связей в предметной области


if (String.IsNullOrEmpty(message))
{

aspnet_Membership me = df.aspnet_Membership.Where(x => x.UserId == newUser.UserId).FirstOrDefault();
if (me != null)
{
df.aspnet_Membership.DeleteObject(me);
}
aspnet_Users asp = GetUserById(newUser.UserId);
df.aspnet_Users.DeleteObject(asp); // в aspnet_UsersInRoles запись должна удалится каскадом

}

df.SaveChanges();

удалять - удаляет, но вот ModelState.IsValid возвращает false. в чем-то проблема. не могу понять в чем дело.
...
Рейтинг: 0 / 0
11.07.2011, 10:28
    #37345654
mar55555
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entitity Framework удаление объектов many-to-many
в Entity Framework информация о каскадном удалении почему-то не поподает
...
Рейтинг: 0 / 0
11.07.2011, 11:25
    #37345796
serkuzm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entitity Framework удаление объектов many-to-many
mar55555,

Да. Не попадает.
У меня схема строится из базы на Firebird. В некоторых связях таблиц установлены каскадные удаления.
При обновлении схемы - не вычитываются (либо не устанавливаются корректными) данные о каскадном удалении.
Как я понял это вопрос не сколько базы данных\провайдера, сколько самого EntityFramework-a.

Все решения что я находил своидились к тому, что нужно вручную править файлы схемы.
Вот пост который помог мне в решении вопроса: Cascade delete in Entity Framework

Теперь после каждого обновления схемы запускается ехе-шник из кода поста и он подправляет сам схему.
У меня работает.

В аттаче - проект из поста.
...
Рейтинг: 0 / 0
11.07.2011, 11:26
    #37345802
mar55555
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entitity Framework удаление объектов many-to-many
спасибо)
...
Рейтинг: 0 / 0
11.07.2011, 11:35
    #37345842
serkuzm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entitity Framework удаление объектов many-to-many
mar55555,

Что-то не получилось приаттачить.
У меня код проекта-парсера для EF 4.0 следующий:


Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.IO;
 using System.Text;
 using System.Xml;

namespace EntityRepareCascadeDelete
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] files = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.edmx");
            XmlDocument doc = new XmlDocument();

            bool aChanged = false;
            foreach (string file in files)
            {
                Console.WriteLine("Load: " + file);
                doc.Load(file);

                System.Xml.XmlNamespaceManager xmlnsManager = new System.Xml.XmlNamespaceManager(doc.NameTable);
                xmlnsManager.AddNamespace("edmx", "http://schemas.microsoft.com/ado/2008/10/edmx");

                XmlNode SSDLNode = doc.SelectSingleNode("//edmx:StorageModels", xmlnsManager).FirstChild;
                XmlNode CSDLNode = doc.SelectSingleNode("//edmx:ConceptualModels", xmlnsManager).FirstChild;

                aChanged = false;
                FixCascadeDeleteIssues(doc, SSDLNode, CSDLNode, ref aChanged);

                if (aChanged)
                {
                    Console.WriteLine("Save: " + file);
                    string backupFile = file + ".bak";
                    if (File.Exists(backupFile))
                        File.Delete(backupFile);

                    File.Move(file, file + ".bak");
                    doc.Save(file);
                }
                else
                {
                    Console.WriteLine("Entity is correct: " + Path.GetFileName(file));
                }
            }

            Console.WriteLine("Press any key…");
            Console.ReadKey();
        }

        private static string MakeKey(string aAssociation, string aRole)
        {
            return aAssociation + "_/\\_" + aRole;
        }

        public static void FixCascadeDeleteIssues(XmlDocument XDOC, XmlNode SSDLNode, XmlNode CSDLNode, ref bool aChanged)
        {
            HashSet<string> lst = new HashSet<string>();

            //
            //
            //
            //
            //
            //
            //
            //

            foreach (XmlNode SSDLChild in SSDLNode)
            {
                if (SSDLChild.Name == "Association")
                {
                    foreach (XmlNode EndChild in SSDLChild)
                    {
                        if (EndChild.Name == "End")
                        {
                            foreach (XmlNode DeleteChild in EndChild)
                            {
                                if (DeleteChild.Name == "OnDelete")
                                {
                                    var x = DeleteChild.Attributes.GetNamedItem("Action");
                                    if (x.Value == "Cascade")
                                    {
                                        lst.Add(MakeKey(SSDLChild.Attributes.GetNamedItem("Name").Value, EndChild.Attributes.GetNamedItem("Role").Value));
                                    }
                                }
                            }
                        }
                    }
                }
            }

            //
            //
            //
            //
            //
            //
            //

            Dictionary<string, string> FMaps = new Dictionary<string, string>();

            foreach (XmlNode CSDLChild in CSDLNode)
            {
                if (CSDLChild.Name == "EntityContainer")
                {
                    foreach (XmlNode ContainerChild in CSDLChild)
                    {
                        if (ContainerChild.Name == "AssociationSet")
                        {
                            foreach (XmlNode EndChild in ContainerChild)
                            {
                                if (EndChild.Name == "End")
                                {
                                    string Association = ContainerChild.Attributes.GetNamedItem("Name").Value;
                                    string Role = EndChild.Attributes.GetNamedItem("Role").Value;
                                    string EntitySet = EndChild.Attributes.GetNamedItem("EntitySet").Value;

                                    FMaps.Add(MakeKey(Association, Role), EntitySet);
                                }
                            }
                        }
                    }
                }
            }

            foreach (XmlNode CSDLChild in CSDLNode)
            {
                if (CSDLChild.Name == "Association")
                {
                    string Association = CSDLChild.Attributes.GetNamedItem("Name").Value;

                    if (Association == "FK_DEV_PARENT_DEV_ID")
                    {
                        Console.WriteLine("");
                    }

                    foreach (XmlNode EndChild in CSDLChild)
                    {
                        if (EndChild.Name == "End")
                        {

                            string Multiplicity = EndChild.Attributes.GetNamedItem("Multiplicity").Value;
                            if (Multiplicity == "*")
                            {
                                continue;
                            }

                            string role = EndChild.Attributes.GetNamedItem("Role").Value;
                            string v;
                            if (FMaps.TryGetValue(MakeKey(Association, role), out v))
                            {
                                role = v;
                            }
                            string key = MakeKey(CSDLChild.Attributes.GetNamedItem("Name").Value, role);

                            if (lst.Contains(key))
                            {
                                bool hasdel = false;
                                foreach (XmlNode DeleteChild in EndChild)
                                {
                                    if (DeleteChild.Name == "OnDelete")
                                    {
                                        var x = DeleteChild.Attributes.GetNamedItem("Action");
                                        if (x.Value == "Cascade")
                                        {
                                            hasdel = true;
                                        }
                                    }
                                }
                                if (!hasdel)
                                {
                                    Console.WriteLine(string.Format("Association ‘{0}’ not have cascade", Association));
                                    XmlNode newSub = XDOC.CreateNode(XmlNodeType.Element, "OnDelete", EndChild.NamespaceURI);
                                    XmlAttribute xa = XDOC.CreateAttribute("Action", null);
                                    xa.Value = "Cascade";
                                    newSub.Attributes.Append(xa);
                                    EndChild.AppendChild(newSub);
                                    aChanged = true;
                                }
                            }
                        }
                    }
                }
            }
        }

    }
}


Возможно будет заморочка с именованием сущностей в "ед. числе" из "множественного числа" в базе... или наоборот... извини, уже не помню ньюансы... Продебаж код парсера если что. Думаю разберешься.

з.ы.
Привет EF!
мля...
...
Рейтинг: 0 / 0
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Entitity Framework удаление объектов many-to-many / 5 сообщений из 5, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]